#conding=utf-8
from django.shortcuts import render
from .models import Device,Building,Scanner,Efence,Alarm,Myuser,Multi_Media,WIFI_LBS_ADDR,Map_Data,Sys_Log,Command_Log,Daily_Report
from django.contrib.auth.models import User
from django.apps import apps
from django.views.decorators.csrf import csrf_exempt 
from django.http import HttpResponseRedirect,Http404,HttpResponse,FileResponse
from django.urls import reverse
from django.forms.models import model_to_dict
from django.contrib.auth import login,logout,authenticate
from django.contrib.auth.decorators import login_required


import redis
import numpy as np
import pandas as pd

from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.views import Response
from data_handle.create_device_table import *

from data_handle.compute.report_compute import start_cacu

import datetime,json,random,time,uuid,requests,math
from math import pi,sin,cos

import base64,threading
# from .phone_app_api import *
from dwebsocket.decorators import accept_websocket,require_websocket
from sqlalchemy import desc
# ffmpeg的python封装，转换音视频，目前用途为转换小程序过来的aac为amr，下发给设备
import ffmpy3


Device_Base = automap_base()
Device_Base.prepare(engine, reflect=True)

pool_redis= redis.ConnectionPool(host='localhost',port=6379,decode_responses=True)
mesg_redis=redis.Redis(connection_pool=pool_redis)

# 操作日志记录
def system_log(request,content,result='success'):
	username=str(request.user)
	visible_name=Myuser.objects.filter(username=username).first().visible_name
	log_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	log_dict={'username':username,'visible_name':visible_name,'remark':'0','content':content,'result':result,'owner':username,
			  'date_added':log_time}
	Sys_Log.objects.create(**(log_dict))

# 系统初次步数之后登陆，创建超级管理员账号
def init_superuser():

	admin_user=Myuser.objects.filter(username='admin').first()
	if admin_user==None:
		superuser={'username':'admin','visible_name':'超级管理员','email':'0','leader':'0','subordinate':'0','level':'0','character':{'kind':'superuser','user_icon':'/static/img/default.png','refresh_time':'60','alarm_audio':'on','alarm_show':'on','handle_device':'yes'},
				   'status':'on','remark':'0'}
		Myuser.objects.create(**(superuser))

init_superuser()



# 登录
@csrf_exempt
def logins(request):
	
	errors=[]
	account=None
	password=None
	what=request.GET.get('what')
	if request.method=='GET':
		if what=='android_apk_down':
			file = open('tracker_app/static/aiot_1.6.08.apk', 'rb')
			response = FileResponse(file)
			response['Content-Type'] = 'application/octet-stream' #设置头信息，告诉浏览器这是个文件
			response['Content-Disposition'] = 'attachment;filename=aiot_1.6.08.apk'
			return response
		elif what=='demo':
			user=authenticate(username='demo',password='123456')
			if user is not None:
				if user.is_active:
					login(request,user)
					errors=0
					# 记录操作日志
					system_log(request,'username')
					user_tree=[]
					# 下级用户列表
					subordinate_user=[]
					# 本次请求的用户名
					user=str(request.user)
					# 获取用户的树状结构信息，并把下级用户信息加入subordinate_user列表
					get_user_tree(user,Myuser,user_tree,subordinate_user)
					# 获取下级用户信息
					user_data=list(Myuser.objects.all().filter(username__in=subordinate_user).values())
					# 获取用户自身的信息
					user_self=list(Myuser.objects.filter(username=user).values())

					# 获取用户和下级用户名下所有的设备信息
					subordinate_user.append(user)
					# print(subordinate_user)
					user_character=eval(user_self[0]['character'])
					device=get_dev_by_userkind(user_character,subordinate_user)
					alarm_data=get_alarm_by_userkind(user_character,subordinate_user)
					all_data={'device':device,'user_tree':user_tree,'user_data':user_data,'user_self':user_self,'alarm_data':alarm_data,
							  }
					return render(request,'tracker_app/index.html',all_data)
					# return HttpResponse(json.dumps('success'))


	if request.method=='POST':

		if not request.POST.get('username'):
			errors.append('请输入用户名')
		else:
			account=request.POST.get('username')
		if not request.POST.get('password'):
			errors.append('请输入密码')
		else:
			password=request.POST.get('password')
		if account is not None and password is not None:
			user=authenticate(username=account,password=password)
			if user is not None:
				user_active=Myuser.objects.filter(username=account).first()

				if user_active!=None:
					if user_active.status=='on':
						login(request,user)
						errors=0
						# 记录操作日志
						system_log(request,'登陆')
						return HttpResponse(json.dumps('success'))
					else:
						errors.append('账号已停止使用')
						system_log(request,'登陆','账号过期')
			else:
				request.user=account
				system_log(request,'登陆','密码/用户名错误')
				errors.append('密码/用户名错误')

		return HttpResponse(json.dumps(errors))

	return render(request,'tracker_app/login.html',{'errors':errors})


# 根据用户类型取数据，常规用户数据依据设备OWNER来区分，手机注册用户绑定的设备，在character里面
def get_alarm_by_userkind(user_character,subordinate_user):
	alarm_data=[]
	if user_character['kind']=='phone_user':
		if user_character.get('bind_dev')!=None:
			alarm_data=list(Alarm.objects.filter(device_id__in=user_character['bind_dev']).filter(handle='no').values())
	else:

		device = list(Device.objects.filter(owner__in=subordinate_user).values())
		device=pd.DataFrame(device)
		alarm_data=[]
		if device.empty==False:
			dev_ids=device['device_id'].tolist()
			alarm_data=list(Alarm.objects.filter(device_id__in=dev_ids).filter(handle='no').values())
		# alarm_data=list(Alarm.objects.filter(owner__in=subordinate_user).filter(handle='no').values())


	return alarm_data

def get_dev_by_userkind(user_character,subordinate_user,map_kind='bd'):
	device=[]
	if user_character['kind']=='phone_user':
		if user_character.get('bind_dev')!=None:
			device=get_phone_user_dev(user_character['bind_dev'],map_kind)
	else:
		device=get_device_detail(subordinate_user,map_kind)
	return device

# 看板
def kanban(request):
	all_data={}
	return render(request,'tracker_app/kanban.html',all_data)

# ----首页start---- #
@login_required
@csrf_exempt
def index(request):
	print('--------------------------index----------------------------')
	user_tree=[]
	# 下级用户列表
	subordinate_user=[]
	# 本次请求的用户名
	user=str(request.user)
	# 获取用户的树状结构信息，并把下级用户信息加入subordinate_user列表
	get_user_tree(user,Myuser,user_tree,subordinate_user)
	# 获取下级用户信息
	user_data=list(Myuser.objects.all().filter(username__in=subordinate_user).values())
	# 获取用户自身的信息
	user_self=list(Myuser.objects.filter(username=user).values())

	# 获取用户和下级用户名下所有的设备信息
	subordinate_user.append(user)
	# print(subordinate_user)
	user_character=eval(user_self[0]['character'])
	# 设备信息
	device=get_dev_by_userkind(user_character,subordinate_user)
	# 设备型号信息
	dev_model=get_device_model()
	# 报警信息
	alarm_data=get_alarm_by_userkind(user_character,subordinate_user)
	# 数据汇总
	all_data={'device':device,'user_tree':user_tree,'user_data':user_data,'user_self':user_self,'alarm_data':alarm_data,'dev_model':dev_model
			  }
	what=request.GET.get('what')
	if request.method=='GET':
		if what=='alarm':
			res={}
			res['alarm_data']=alarm_data
			res['device']=device
			return HttpResponse(json.dumps(res))
		elif what=='kanban':
			kanban_data=handle_kanban(request)
			return HttpResponse(json.dumps(kanban_data))
	if request.method=='POST':
		log_content=request.GET.get('what')
		

		# 报警信息处理
		if what=='alarm_handle':
			alarm_id=eval(request.POST.get('device_id'))
			handle_data=request.POST.get('alarm_handle_mark')
			
			for x in alarm_id:
				Alarm.objects.filter(id=x).update(handle=handle_data)

			alarm_data=get_alarm_by_userkind(user_character,subordinate_user)
			system_log(request,'处理-'+str(alarm_id+'-报警'))
			return HttpResponse(json.dumps(alarm_data))

		# 用户基本设置处理
		elif what=='handle_user_self':
			
			handle_data=eval(request.POST.get('result'))
			handle_data['level']=str([handle_data.pop('contact'),handle_data.pop('phone')])
			param_to_db=Myuser.objects.filter(username=request.user).first()
			character=eval(param_to_db.character)

			#显示图标，判断过来的数据是否超过100字节，超过说明是baase64的数据进行生成图片处理，把路径更新
			user_icon=handle_data.pop('file')

			if len(user_icon)>100:
				sys_platform=sys.platform[0:3]

				# 创建路径，有的话不用理会
				try:
					path=''
					if sys_platform=='win':
						path='E:\\tracker\\tracker_app\\static\\data_from_web\\user\\'+str(request.user)+'\\'
					else:
						path='/root/tracker/tracker_app/static/data_from_web/user/'+str(request.user)
					os.makedirs(path)
				except:
					pass

				if sys_platform=='win':
					img_name='tracker_app/static/data_from_web/user/'+str(request.user)+'/system_icon.png'
				else:
					img_name='/root/tracker/tracker_app/static/data_from_web/user/'+str(request.user)+'/system_icon.png'
				fh = open(img_name,"wb")
				user_icon=user_icon.split(',')[1]
				img = base64.b64decode(user_icon)
				fh.write(img)
				fh.close()
				character['user_icon']='/static/data_from_web/user/'+str(request.user)+'/system_icon.png'

			alarm_show=handle_data.pop('alarm_show')
			alarm_audio=handle_data.pop('alarm_audio')
			refresh_time=handle_data.pop('refresh_time')
			sys_name=handle_data.pop('sys_name')
			character.update(alarm_show=alarm_show,alarm_audio=alarm_audio,refresh_time=refresh_time,sys_name=sys_name)
			handle_data['character']=character

			Myuser.objects.filter(username=request.user).update(**(handle_data))
			system_log(request,'修改用户基本设置')

			return HttpResponse(json.dumps('ok'))

		# 修改密码
		elif what=='handle_user_password':
			handle_data=eval(request.POST.get('result'))
			old_password=handle_data['old_password']
			new_password=handle_data['new_password1']
			username=request.user
			user = authenticate(username=username, password=old_password)

			if user is not None:
				user.set_password(new_password)
				user.save()
				system_log(request,'修改密码')
				return HttpResponse(json.dumps(['修改密码成功']))

			else:
				system_log(request,'修改密码','失败')
				return HttpResponse(json.dumps(['修改密码失败']))

		

	return render(request,'tracker_app/index.html',all_data)


def handle_kanban(request):
	# 获取本月初到当前的时间范围
	now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	mon_start=now_time.split(' ')
	day_start=mon_start[0].split('-')
	mon_start[1]='00:00:00'
	day_start[2]='01'
	mon_start[0]='-'.join(day_start)
	mon_start=' '.join(mon_start)
	# 获取相应数据
	querydata=Daily_Report.objects.filter(analysis_time__lt=now_time).filter(analysis_time__gte=mon_start).values()
	querydata=list(querydata)
	querydata=pd.DataFrame(querydata)
	querydata=querydata.sort_values('analysis_time')
	querydata=querydata.reset_index(drop=True)
	rp_data=querydata.loc[querydata['device_id']=='total'].copy()

	alarm_kind={'heart_alarm':0,'efence':0,'stop_alarm':0,'blood_alarm':0,
				'sos_alarm':0,'fall_down':0,'heart_high':0,'heart_low':0,
				'l_pres_heig':0,'l_pres_low':0,'h_pres_heig':0,'h_pres_low':0,
				'polygon':0,'rectangle':0,'circle':0,'low_power':0}

	alarm_kind_data=rp_data['alarm_kind'].tolist()

	def handle_alarm(alarm_x,alarm_y):
		for x in alarm_x:
			if x!='0':
				x=eval(x)
				for y in x:
					alarm_y[y]=alarm_y[y]+int(x[y])
		return alarm_y

	alarm_kind=handle_alarm(alarm_kind_data,alarm_kind)

	alarm_time={'00':0,'01':0,'02':0,'03':0,'04':0,'05':0,'06':0,'07':0,'08':0,'09':0,'10':0,'11':0,'12':0,'13':0,'14':0,'15':0,'16':0,'17':0
								,'18':0,'19':0,'20':0,'21':0,'22':0,'23':0}
	alarm_time_data=rp_data['alarm_time'].tolist()

	alarm_time=handle_alarm(alarm_time_data,alarm_time)
	time_order=['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23']
	alarm_time_res=[]
	for x in time_order:
		alarm_time_res.append(alarm_time[x])

	rp_data.loc[:,'h_pres']=rp_data['blood_pres'].map(lambda x:eval(x)['h_pres'] if x!='0' else 0)
	rp_data.loc[:,'l_pres']=rp_data['blood_pres'].map(lambda x:eval(x)['l_pres'] if x!='0' else 0)
	# print('rp_data_lpres====>',int(pd.to_numeric(rp_data['heart_rate']).mean()))
	collect_data= dict(
		active=pd.to_numeric(rp_data['active']).tolist(),
		online=pd.to_numeric(rp_data['online']).tolist(),
		alarm_time=alarm_time_res,
		alarm_kind=alarm_kind,
		alarm_location=rp_data['alarm_location'].tolist(),
		heart_rate=int(pd.to_numeric(rp_data['heart_rate']).mean()),
		h_pres=int(rp_data['h_pres'].mean()),
		l_pres=int(rp_data['l_pres'].mean()),
		step_count=int(pd.to_numeric(rp_data['step_count']).mean()),
		mileage=int(pd.to_numeric(rp_data['mileage']).mean()),
		calorie=int(pd.to_numeric(rp_data['calorie']).mean()),
		stop_time=round(int(pd.to_numeric(rp_data['stop_time']).mean())/3600,1),
		sleep=round(int(pd.to_numeric(rp_data['sleep']).mean())/3600,1)
		)

	h_list=['active','online']
	def change_style(data,kind):
		for i in range(len(data)):
			if data[i]!=0:
				data[i]=round(data[i]/864)
		return data
	for x in h_list:
		collect_data[x]=change_style(collect_data[x],x)
	# print('collect_data====>',collect_data)
	# 计算健康数据排名
	rank_data=querydata.loc[querydata['device_id']!='total'].copy()
	rank_data.loc[:,'health_points']=rank_data['attch_analysis'].map(lambda x:eval(x)['health_points'] if x!='0' else '0')
	health_rank_data=rank_data.loc[rank_data['health_points']!=0].copy()
	if health_rank_data.shape[0]>0:
		health_rank_data['health_points']=pd.to_numeric(health_rank_data['health_points'])
		health_rank=health_rank_data.groupby('device_id')['health_points'].mean()
		if health_rank.shape[0]>5:
			health_rank=health_rank.head(5).to_dict()
		else:
			health_rank=health_rank.to_dict()
		collect_data['health_rank']=health_rank
		# print(health_rank)

	# 报警排名计算
	alarm_data=Alarm.objects.filter(s_time__lt=now_time).filter(s_time__gte=mon_start).values()
	alarm_data=list(alarm_data)
	alarm_data=pd.DataFrame(alarm_data)
	if alarm_data.empty==False:
		alarm_rank=alarm_data.groupby('device_id')['kind'].count()
		if alarm_rank.shape[0]>5:
			alarm_rank=alarm_rank.head(5).to_dict()
		else:
			alarm_rank=alarm_rank.to_dict()

		collect_data['alarm_rank']=alarm_rank
		# print(alarm_rank)

	return collect_data

# ----首页end---- #

# 增删改查函数
def database_handle(title,what,table,field,handle_data,subordinate_user):
	# print('handle_data====>',handle_data)
	res = {'code':1000,'error':'','data':''}
	key_word=''
	if what!='add_from_file':
		key_word=handle_data[field]
	else:
		key_word=handle_data
	target_user=''
	# 单个新增
	if what=='add':
		# 重名判断
		# key_word=handle_data[field]
		if table.objects.filter(**({field:key_word})).first()!=None:
			res['code']=1234
			res['error']=key_word+'已存在，请使用其他名称/id'
		else:
			table.objects.create(**(handle_data))

	# 设备通过文件批量新增
	elif what=='add_from_file':
		for add_data in handle_data:
			table.objects.create(**(add_data))
			
	# 编辑修改
	elif what=='edit':
		# key_word=handle_data.pop(field)
		table.objects.filter(**({field:key_word})).update(**(handle_data))

	# 删除
	elif what=='del':
		# key_word=handle_data.pop(field)
		table.objects.filter(**({field:key_word})).delete()
	# 转移
	elif what=='change_owner':
		# key_word=handle_data[field]
		target_user=handle_data['target_user']
		for n in key_word:
			table.objects.filter(**({field:n})).update(owner=target_user)

	result='failed'
	current_user=subordinate_user[-1]
	if(res['code']==1000):
		send_data=''
		if field=='username':
			subordinate_user.remove(subordinate_user[-1])
			send_data=list(table.objects.all().filter(username__in=subordinate_user).values())
		else:
			send_data=list(table.objects.all().filter(owner__in=subordinate_user).values())
		res['data']=send_data
		result='success'

	# 记录操作日志
	# print('target_user====>',,target_user,handle_data)
	handle_kind_list={'add':'新增'+title+':'+str(key_word),'add_from_file':'批量新增'+title+':'+str(key_word),'edit':'修改'+title+':'+str(key_word),'del':'删除'+title+':'+str(key_word),'change_owner':'转移'+title+':'+str(key_word)+'到'+target_user}
	log_content=handle_kind_list[what]
	visible_name=Myuser.objects.filter(username=current_user).first().visible_name
	log_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	log_dict={'username':current_user,'visible_name':visible_name,'remark':'0','content':log_content,'result':result,'owner':current_user,
			  'date_added':log_time}
	Sys_Log.objects.create(**(log_dict))

	return res

# ----设备管理start---- #
# 获取设备型号
def get_device_model(file_path=''):
	file_path='E:\\tracker\\data_handle\\device_model.xlsx'
	sys_platform=sys.platform[0:3]
	if file_path=='':
		if sys_platform=='win':
			path='E:\\tracker\\data_handle\\device_model.xlsx'
		else:
			path='/root/tracker/data_handle/device_model.xlsx'
	detail=pd.read_excel(file_path,sheetname = None)
	for x in detail:
		detail[x]=detail[x].fillna('无')
	base_data=detail['基本数据'].to_json(orient="records",force_ascii=False)
	base_data=eval(base_data)
	datakind=detail['数据种类'].to_json(orient="records",force_ascii=False)
	datakind=eval(datakind)
	command=detail['命令下发'].to_json(orient="records",force_ascii=False)
	command=eval(command)
	param_set=detail['参数设置'].to_json(orient="records",force_ascii=False)
	param_set=eval(param_set)
	alarm_set=detail['报警类型'].to_json(orient="records",force_ascii=False)
	alarm_set=eval(alarm_set)
	for x in base_data:
		# print(x)
		for y in datakind:
			if x['unique_id']==y['unique_id']:
				x['datakind']=y
				# x['datakind'].pop('unique_id')
		for z in command:
			if x['unique_id']==z['unique_id']:
				x['command']=z
		for n in param_set:
			if x['unique_id']==n['unique_id']:
				x['param_set']=n
		for l in alarm_set:
			if x['unique_id']==l['unique_id']:
				x['alarm_set']=l

	return base_data

@login_required
@csrf_exempt
def device(request):
	res = {'code':1000,'error':'','data':''}
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	what=request.GET.get('what')
	if request.method=='GET':
		if what=='get_init_data':
			dev_model=get_device_model()
			dev_data=list(Device.objects.all().filter(owner__in=subordinate_user).values())
			res['dev_model']=dev_model
			res['main']=dev_data
			return HttpResponse(json.dumps(res))

	if request.method=='POST':
		handle_data=eval(request.POST.get('base_info'))
		save_data=handle_data.copy()
		print(handle_data)

		# 添加单台设备
		if what=='add':
			save_data=package_device_data(save_data,request,subordinate_user)
		# 设备通过文件批量导入设备
		elif what=='add_from_file':

			result=[]
			for device_data in save_data:
				new_data=package_device_data(device_data,request,subordinate_user)
				result.append(new_data)
			save_data=result
				
		# 对设备进行转移分配处理，需要进行单独的解绑处理，把绑定的用户信息和围栏信息清空
		
		elif what in ['change_owner','del']:
			device_list=[]
			if what=='change_owner':
				device_list=handle_data['device_id']
			elif what=='del':
				device_list.append(handle_data['device_id'])
				drop_table(handle_data['device_id'])

			for device_id in device_list:
				# 历遍device绑定的围栏，把相应围栏里面相应的device_id去掉
				efe_of_dev=Device.objects.filter(device_id=device_id).first().efence
				if efe_of_dev!='0':
					if isinstance(eval(efe_of_dev),dict)==True:
						for efence_name in eval(efe_of_dev):
							efence_device_list=Efence.objects.filter(name=efence_name).first().device_id
							efence_device_list=eval(efence_device_list)
							if device_id in efence_device_list:
								efence_device_list.remove(device_id)
							Efence.objects.filter(name=efence_name).update(device_id=str(efence_device_list))

				# 把device里的efence围栏信息，user_detail用户信息的信清空，用户归属更改为目标用户
				Device.objects.filter(device_id=device_id).update(efence='0')

		hanlde_result=database_handle('设备',what,Device,'device_id',save_data,subordinate_user)
		
		return HttpResponse(json.dumps(hanlde_result))


	return render(request,'tracker_app/device.html')

def package_device_data(org_data,request,subordinate_user):

	org_data['auth_id']=str(random.randint(1000,9999))
	if org_data['user_name']=='':
		org_data['user_name']=org_data['device_id']
	# org_data['dynamic']='0'
	# org_data['user_detail']={'user_name':org_data['user_name'],'department':'0','c_model':'0','insurance':'0','maitain':'0','driver':'0','icon_show':'0'}
	# org_data['param_set']={'send_rate':'30','speed_limit':'180','efence':'0','stop_rate':'0'}
	# 对设备的dynamic动态信息做初始化设置，对应的后台应该判断基本参数的动态信息是否有具体内容，如果为零，则不做计算判断处理。
	dynamic_field={'lng':'0','lat':'0','lbs':'0','wifi':'0',
						'rssi':'0','heart_rate':'0','blood_pres':'0','step_count':'0',
						'obd':'0','track_type':'0','speed':'0','dirct':'0','status':'0',
						'battery':'0','sos_alarm':'0','dev_upload':'0','serv_receive':'0','hard_verson':'0',
						'mileage':'0','oil_use':'0','efence_alarm':'0','speed_alarm':'0','stop_time':'0',
						'location':'0','othermesg':'0','scanner':'0','heart_alarm':'0','blood_alarm':'0',
						'receive_port':'0'}
	org_data['dynamic']=dynamic_field
	if org_data.get('owner')==None:
		org_data['owner']=str(request.user)
	else:
		if org_data['owner'] not in subordinate_user:
			org_data['owner']=str(request.user)
	# 创建一条设备信息
	# 创建一张以设备tracker+ID的独立数据表，用来存储该设备的所有数据历史数据
	print(org_data['device_id'],type(org_data['device_id']))
	creat_device_table(org_data['device_id'])
	return org_data

# ----设备管理end---- #





#刷新数据库连接
def refresh_session(device_id):
	global Device_Base
	if not Device_Base.classes.has_key(device_id):
		engine = create_engine('postgres://postgres:123456@localhost:5432/tracker')    
		Device_Base = automap_base()
		Device_Base.prepare(engine, reflect=True)
	return


#用户管理页面
@csrf_exempt
def user_manage(request):
	res = {'code':1000,'error':'','data':''}
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	what=request.GET.get('what')
	
	if request.method=='POST':
		handle_data=eval(request.POST.get('base_info'))
		if what=='add':
			# 增加数据
			handle_data['leader']=str(request.user)
			handle_result=database_handle('子用户',what,Myuser,'username',handle_data,subordinate_user)
			# 在django自带的user里面创建用户，用户登录和登出的操作
			User.objects.create_user(username=handle_data['username'],password='123456')
			# 把新建的子账号添加到子用户列表
			old_subordinate=Myuser.objects.filter(username=request.user).first().subordinate
			if old_subordinate=='0':
				Myuser.objects.filter(username=request.user).update(subordinate=handle_data['username'])
			else:
				Myuser.objects.filter(username=request.user).update(subordinate=old_subordinate+','+handle_data['username'])
			subordinate_user.append(handle_data['username'])
			user_data=list(Myuser.objects.filter(username__in=subordinate_user).values())
			handle_result['data']=user_data
			return HttpResponse(json.dumps(handle_result))

		# 修改数据
		elif what=='edit':
			handle_result=database_handle('子用户',what,Myuser,'username',handle_data,subordinate_user)
			return HttpResponse(json.dumps(handle_result))
		# 重置密码
		elif what=='reset_pwd':
			
			user = User.objects.get(username=handle_data['username'])
			if user is not None:
				user.set_password('123456')
				user.save()
				res['data']='重置密码成功,新密码：123456'
			else:
				res['code']=1234
				res['data']='重置密码失败'

			system_log(request,'重置密码-'+handle_data['username'],res['data'])

			return HttpResponse(json.dumps(res))


		#用户启用停用处理
		elif what=='user_status':
			handle_data=eval(request.POST.get('base_info'))
			title=''
			if handle_data['status']=='on':
				title='停用账号-'+handle_data['username']
				User.objects.filter(username=handle_data['username']).update(is_active=False)
				Myuser.objects.filter(username=handle_data['username']).update(status='off')
			else:
				title='启用账号-'+handle_data['username']
				User.objects.filter(username=handle_data['username']).update(is_active=True)
				Myuser.objects.filter(username=handle_data['username']).update(status='on')

			user_data=list(Myuser.objects.all().filter(username__in=subordinate_user).values())
			res['data']=user_data
			system_log(request,title)
			return HttpResponse(json.dumps(res))

	return render(request,'tracker_app/user_manage.html')



@csrf_exempt
def building(request):

	what=request.GET.get('what')
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	# Building.objects.filter(name='仓库').update(camera='0',scanner='0')
	if request.method=='GET':

		if what=='get_init_data':
			building=Building.objects.filter(owner__in=subordinate_user).values()
			building=list(building)
			res={'main':building,'other':''}
			return HttpResponse(json.dumps(res))

	if request.method=='POST':

		handle_data=eval(request.POST.get('base_info'))
		if what=='add':
			handle_data['owner']=str(request.user)
		save_data=handle_data.copy()

		# 删除建筑，需要解绑地图和基站上的建筑信息
		if what=='del':
			name=handle_data['name']

			build_detail=Building.objects.filter(name=name).first()
			if build_detail!=None:
				# 确定该建筑所在的地图，把该建筑从地图的overlay上消除，地图上的overlay数据格式{building:[],camera:[],sacnner:[]}
				position=build_detail.position
				if position!='0' and position!='':
					position=eval(position)
					map_name=position['map']
					map_detail=Map_Data.objects.filter(name=map_name).first()
					if map_detail!=None:
						overlay=eval(map_detail.overlay)
						building_on_map=overlay['building']
						for x in building_on_map:
							if x['name']==name:
								overlay['building'].remove(x)
						Map_Data.objects.filter(name=map_name).update(overlay=str(overlay))

				# 确定安装在该建筑的基站和摄像头，把对应的基站和摄像头位置信息里面的building信息清空

				# 解绑基站信息
				scanner=build_detail.scanner
				if scanner!='0' and scanner!='':
					scanner=eval(scanner)
					for x in scanner:
						scanner_detail=Scanner.objects.filter(device_id=x).first()
						if scanner_detail!=None:
							c_p=scanner_detail.position
							if c_p!='0' and c_p!='':
								c_p=eval(c_p)
								c_p['building']=''
								Scanner.objects.filter(device_id=x).update(position=str(c_p))

		hanlde_result=database_handle('建筑',what,Building,'name',save_data,subordinate_user)
		return HttpResponse(json.dumps(hanlde_result))

	return render(request,'tracker_app/building.html')


# 操作日志查询
@csrf_exempt
def sys_log_web(request):
	if request.GET.get('what')=='get_log_data':
		subordinate_user=get_subordinate_user(request,Myuser)
		subordinate_user.append(str(request.user))
		sys_log_data=list(Sys_Log.objects.all().filter(owner__in=subordinate_user).values())
		return HttpResponse(json.dumps(sys_log_data))

	if request.method=='POST':
		if request.GET.get('what')=='query_log':
			query_param=eval(request.POST.get('query_param'))
			user_list=query_param['hard_id']
			s_time=query_param['s_time']
			e_time=query_param['e_time']
			
			log_detail=Sys_Log.objects.filter(owner__in=user_list).filter(date_added__lt=e_time).filter(date_added__gt=s_time).values()

			return HttpResponse(json.dumps(list(log_detail)))

		
		
@csrf_exempt
def scanner(request):
	res = {'code':1000,'error':'','data':''}
	what=request.GET.get('what')
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	if request.method=='GET':

		if what=='get_init_data':
			res_data={}
			scanner=Scanner.objects.filter(owner__in=subordinate_user).values()
			scanner=list(scanner)
			building=Building.objects.filter(owner__in=subordinate_user).values()
			building=list(building)
			res_data['main']=scanner
			res_data['other']=building
			return HttpResponse(json.dumps(res_data))

	if request.method=='POST':

		handle_data=eval(request.POST.get('base_info'))
		if what=='add':
			handle_data['owner']=str(request.user)
		save_data=handle_data.copy()
		# 修改安装位置的时候，需要解绑旧的安装建筑,绑定新的建筑，
		# 修改安装位置的时候，需要解绑地图上的安装位置，绑定新的建筑
		# 删除基站的时候，需要解绑安装的建筑
		# 删除的时候，需要在地图上解绑相应基站
		handle_bind_build(what,Scanner,handle_data,'scanner')
		hanlde_result=database_handle('基站',what,Scanner,'device_id',save_data,subordinate_user)

		return HttpResponse(json.dumps(hanlde_result))
	return render(request,'tracker_app/scanner.html')

def handle_bind_build(what,table,new_data,kind):
	# 添加新的基站或者摄像头,有确定安装位置的，绑定相关安装位置
	# 获取旧的安装位置，
	old_build=None
	map_name=''
	device_id=new_data['device_id']
	main_detail=table.objects.filter(device_id=device_id).first()
	if main_detail!=None:
		position=main_detail.position
		if position!='0':
			position=eval(position)
			old_build=position['building']
			old_build=Building.objects.filter(name=old_build).first()
			map_name=position['map']

	# 新的安装建筑信息
	new_build=''
	if new_data['position']!='0':
		new_build=eval(new_data['position'])['building']
	new_build=Building.objects.filter(name=new_build).first()
	# 绑定到建筑
	def bind_to_build(new,obj_id):
		if new!=None:
			new=vars(new)
			target=new[kind]
			if target=='' or target=='0':
				target=[obj_id]
			else:
				target=eval(target)
				target.append(obj_id)

			Building.objects.filter(name=new['name']).update(**({kind:str(target)}))
	# 从建筑解绑
	def dismiss_to_build(old,obj_id):
		if old!=None:
			old=vars(old)
			target=old[kind]
			target=eval(target)
			target.remove(obj_id)

			Building.objects.filter(name=old['name']).update(**({kind:str(target)}))

	if what=='add':
		bind_to_build(new_build,device_id)
			
	elif what=='edit':
		dismiss_to_build(old_build,device_id)
		bind_to_build(new_build,device_id)

	elif what=='del':
		dismiss_to_build(old_build,device_id)
		map_detail=Map_Data.objects.filter(name=map_name).first()
		if map_detail!=None:
			overlay=eval(map_detail.overlay)
			overlay_on_map=overlay[kind]
			for x in overlay_on_map:
				if x['name_id']==device_id:
					overlay[kind].remove(x)
			Map_Data.objects.filter(name=map_name).update(overlay=str(overlay))


@csrf_exempt
def map_manage(request):
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	res = {'code':1000,'error':'','data':''}
	what=request.GET.get('what')
	bd_map=str(request.user)+'_bd_map'
	if Map_Data.objects.filter(name=bd_map).first()==None:
		map_obj={'name':bd_map,'kind':'bd_map','owner':str(request.user)}
		Map_Data.objects.create(**(map_obj))
	if request.method=='GET':

		if what=='get_map_data':
			
			map_data=Map_Data.objects.filter(owner__in=subordinate_user).values()
			map_data=list(map_data)

			sys_platform=sys.platform[0:3]
			path=''
			if sys_platform=='win':
				path='E:\\tracker\\tracker_app\\static\\map_data\\'
			else:
				path='/root/tracker/tracker_app/static/map_data/'
			map_file_list=[]
			for root,dirs,files in os.walk(path):
				map_file_list=files
			# 去掉已经添加在表单的地图文件
			for x in map_data:
				if x['content'] in map_file_list:
					map_file_list.remove(x['content'])
			all_data={'map_data':map_data,'map_file_list':map_file_list}
			return HttpResponse(json.dumps(all_data))

	if request.method=='POST':
		if what=='add':
			handle_data=eval(request.POST.get('base_info'))
			repeat_name=Map_Data.objects.filter(name=handle_data['name']).first()
			if repeat_name!=None:
				res['code']=1234
				res['error']='名字重复'
				return HttpResponse(json.dumps(res))
			handle_data['owner']=str(request.user)
			Map_Data.objects.create(**(handle_data))
			# 给前端返回更新后的数据
			map_data=Map_Data.objects.filter(owner__in=subordinate_user).values()
			map_data=list(map_data)
			res['data']=map_data
			print(res)
			return HttpResponse(json.dumps(res))
	return render(request,'tracker_app/map_manage.html')

# 地图编辑
@csrf_exempt
def overlay_to_map(request):
	subordinate_user=get_subordinate_user(request,Myuser)
	subordinate_user.append(str(request.user))
	res = {'code':1000,'error':'','data':''}
	what=request.GET.get('what')
	if request.method=='GET':
		if what=='get_overlay':
			building=Building.objects.filter(owner__in=subordinate_user).values()
			building=list(building)
			scanner=Scanner.objects.filter(owner__in=subordinate_user).values()
			scanner=list(scanner)
			all_data={'building':building,'scanner':scanner}
			return HttpResponse(json.dumps(all_data))
	if request.method=='POST':
		if what=='add_overlay':
			handle_data=eval(request.POST.get('base_info'))

			map_name=handle_data.pop('map_name')
			overlay_kind=handle_data['overlay_kind']
			overlay_name=handle_data['name']
			overlay_positon={'map':map_name,'location':handle_data['location']}
			if overlay_kind!='building':
				overlay_name=handle_data['name_id']
				overlay_positon={'map':map_name,'building':handle_data['building_name'],'location':handle_data['location']}

			obj_to_map={'name':handle_data['name'],'name_id':handle_data['name_id'],'location':handle_data['location'],'kind':handle_data['kind']}
			
			# 更新地图的overlay信息
			map_data=Map_Data.objects.filter(name=map_name).first()
			if map_data!=None:
				if map_data.overlay=='0':
					Map_Data.objects.filter(name=map_name).update(overlay=str({overlay_kind:[obj_to_map]}))
				else:
					map_overlay=eval(map_data.overlay)
					if map_overlay.get(overlay_kind)==None:
						map_overlay[overlay_kind]=[obj_to_map]
					else:
						map_overlay[overlay_kind].append(obj_to_map)
					Map_Data.objects.filter(name=map_name).update(overlay=str(map_overlay))

			# 更新建筑，摄像头和基站的位置信息
			db_table=Building
			if overlay_kind=='scanner':
				db_table=Scanner
				fild_name='device_id'
			elif overlay_kind=='camera':
				db_table=Camera
				fild_name='device_id'

			if overlay_kind=='building':
				db_table.objects.filter(name=overlay_name).update(position=str(overlay_positon))
			else:
				bind_data={'position':str(overlay_positon),'device_id':overlay_name}
				handle_bind_build('add',db_table,bind_data,overlay_kind)
				db_table.objects.filter(device_id=overlay_name).update(position=str(overlay_positon))
				

			map_data=Map_Data.objects.filter(name=map_name).first()
			map_data=vars(map_data)
			map_data.pop('_state')
			res['data']=map_data

			return HttpResponse(json.dumps(res))

		if what=='reset_overlay':
			handle_data=eval(request.POST.get('base_info'))

			map_name=handle_data.pop('map_name')
			overlay_kind=handle_data['overlay_kind']
			overlay_name=handle_data['name']
			edit_target='name'
			if overlay_kind!='building':
				overlay_name=handle_data['name_id']
				edit_target='name_id'
			# 更新地图的overlay信息
			map_data=Map_Data.objects.filter(name=map_name).first()
			if map_data!=None:
				if map_data.overlay!='0':
					map_overlay=eval(map_data.overlay)
					if map_overlay.get(overlay_kind)!=None:
						overlays=map_overlay[overlay_kind].copy()
						for x in map_overlay[overlay_kind]:
							if x[edit_target]==overlay_name:
								overlays.remove(x)
						map_overlay[overlay_kind]=overlays
						Map_Data.objects.filter(name=map_name).update(overlay=str(map_overlay))

			# 更新建筑，摄像头和基站的位置信息
			db_table=Building
			if overlay_kind=='scanner':
				db_table=Scanner
			elif overlay_kind=='camera':
				db_table=Camera

			if overlay_kind=='building':
				db_table.objects.filter(name=overlay_name).update(position='0')
			else:
				bind_data={'position':str({'map':'','building':'','location':''}),'device_id':overlay_name}
				handle_bind_build('edit',db_table,bind_data,overlay_kind)
				db_table.objects.filter(device_id=overlay_name).update(position=str({'map':'','building':'','location':''}))
				

			map_data=Map_Data.objects.filter(name=map_name).first()
			map_data=vars(map_data)
			map_data.pop('_state')
			res['data']=map_data

			return HttpResponse(json.dumps(res))
	return render(request,'tracker_app/overlay_to_map.html')

# 实时监控页面渲染
@login_required
@csrf_exempt
def dynamic(request):
	
	if request.method=='GET':

		what=request.GET.get('what')
		if what=='get_new_device':
			subordinate_user=get_subordinate_user(request,Myuser)
			subordinate_user.append(str(request.user))
			user_character=eval(Myuser.objects.get(username=request.user).character)
			device=get_dev_by_userkind(user_character,subordinate_user)
			return HttpResponse(json.dumps(device))

	if request.method=='POST':
		what=request.GET.get('what')
		# system_log(request,log_content)

		#报警参数设置数据处理（系统参数设定，绑定设备，不改变硬件本身的参数）
		if what=='alarm_set':
			alarm_set_data=eval(request.POST.get('alarm_set_data'))
			device_id=alarm_set_data.pop('device_id')
			param_set=Device.objects.filter(device_id=device_id).first()
			if param_set!=None:
				param_set=param_set.param_set
				if isinstance(param_set,str)==True:
					param_set=eval(param_set)
					if isinstance(param_set,dict)==True:
						param_set.update(alarm_set_data)
					else:
						param_set=alarm_set_data
				else:
					param_set=alarm_set_data

			Device.objects.filter(device_id=device_id).update(param_set=param_set)
			result=[{'device_id':device_id,'param_set':param_set}]
			return HttpResponse(json.dumps(result))

		#设备硬件参数设置（给设备发指令，改变硬件本身的参数）
		elif what=='device_set':
			
			param_data=eval(request.POST.get('param_data'))
			req_user=str(request.user)
			res=handle_command(param_data,req_user,'device_set')

			return HttpResponse(json.dumps(res))

		#给设备下发命令
		elif what=='order_dowm':
			print('order_dowm')
			param_data=eval(request.POST.get('param_data'))
			req_user=str(request.user)
			res_data=handle_command(param_data,req_user,'order')
	
			return HttpResponse(json.dumps(res_data))

		# 手机用户绑定设备
		elif what=='phone_user_bind_dev':

			res=BaseResponse()
			device_id=request.POST.get('device_id')
			auth_id=request.POST.get('auth_id')
			dev_detail=Device.objects.get(device_id=device_id)

			if auth_id==dev_detail.auth_id:
				print(request.user,str(request.user))
				phone_user=Myuser.objects.get(username=str(request.user))
				character=eval(phone_user.character)
				bind_dev=''
				if character.get('bind_dev')!=None:
					bind_dev=character['bind_dev']
					bind_dev.append(device_id)
					character['bind_dev']=bind_dev
				else:
					bind_dev=[device_id]
					character['bind_dev']=bind_dev
				character=str(character)
				Myuser.objects.filter(username=request.user).update(character=character)
				device_data=get_phone_user_dev(bind_dev)
				res.code=1000
				res.data=device_data
			else:
				res.code=1024
				res.error='授权码错误'

			return HttpResponse(json.dumps(res.dict))

		# 获取wifi或者lbs地址
		elif what=='get_wifi_lbs_addr':
			track_type=request.POST.get('track_type')
			# mac=request.POST.get('mac')
			# ssid=request.POST.get('ssid')
			# rssi=request.POST.get('rssi')
			device_id=request.POST.get('device_id')
			dev_dynamic=Device.objects.get(device_id=device_id)
			address_result=''
			if dev_dynamic!=None:
				dev_dynamic=eval(dev_dynamic.dynamic)
				dev_wifi=dev_dynamic[track_type]
				address_result=eval('get_'+track_type+'_address(x,'+device_id+')')

			print(address_result)
			lng=float(address_result[0])
			lat=float(address_result[1])
			address=[{'lng':lng,'lat':lat}]
			print('address=====',address)
			return HttpResponse(json.dumps(address))


	return render(request,'tracker_app/dynamic.html')


def get_phone_user_dev(device_id,map_kind='bd'):
	# sql_device = 'select * from tracker_app_device where device_id=\''+device_id+'\''

	device = Device.objects.filter(device_id__in=device_id)
	device_data=pd.DataFrame(device)
	device_data=device_data[0].map(lambda x:vars(x))
	device_data.apply(lambda x:x.pop('_state'))
	device_data=device_data.tolist()
	device_data=pd.DataFrame(device_data)

	# 判断是否有device
	if device_data.shape[0]>0:
		# 判断该用户名下是否有设备
		device_data=device_data.loc[device_data['dynamic']!='0']
		if device_data.shape[0]>0:
			device_data=handle_dynamic_data(device_data,map_kind)
			return device_data
	return []

# 实时考勤
def realtime_attendance(request):
	return render(request,'tracker_app/realtime_attendance.html')


#互动交流
# @csrf_exempt
# def interact(request):
# 	return render(request,'tracker_app/interact.html')


#轨迹回放
@csrf_exempt
def trail(request):


	if request.method=='POST' and request.GET.get('what')=='get_trail':
		start=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
		log_content=request.GET.get('what')
		system_log(request,log_content)

		trail_param=request.POST.get('trail_param')
		trail_param=eval(trail_param)
		device_id=trail_param['device_id']
		s_time=trail_param['s_time']
		e_time=trail_param['e_time']
		track_kind=trail_param['trail_filter']
		map_kind=trail_param['map_kind']

		refresh_session(device_id)
		trail_detail_data=handle_trail(device_id,s_time,e_time,track_kind,map_kind)

		return HttpResponse(json.dumps(trail_detail_data))

	device_check=''
	if request.GET.get('params'):
		params=request.GET.get('params')
		for x in devices_all:
			if x['device_id']==params:
				device_check=x
	else:
		device_check='0'

	return render(request,'tracker_app/trail.html')

# 电子围栏页面

def handle_efence_by_mapkind(efe,map_kind,method='get'):
	# print('old==========>',efe)
	if method=='get':
		for x in range(len(efe)):
			efe[x]['content']=eval(efe[x]['content'])
			if efe[x]['kind']=='circle':
				centre=efe[x]['content'][1]
				if map_kind=='bd':
					efe[x]['content'][1]=wgs84_to_bd09(centre['lng'],centre['lat'])
				elif map_kind=='gd':
					efe[x]['content'][1]=wgs84_to_gcj02(centre['lng'],centre['lat'])

			elif efe[x]['kind'] in ['polygon','rectangle']:
				for y in range(len(efe[x]['content'])):
					if map_kind=='bd':
						efe[x]['content'][y]=wgs84_to_bd09(efe[x]['content'][y]['lng'],efe[x]['content'][y]['lat'])
					elif map_kind=='gd':
						efe[x]['content'][y]=wgs84_to_gcj02(efe[x]['content'][y]['lng'],efe[x]['content'][y]['lat'])
			efe[x]['content']=str(efe[x]['content'])

	elif method=='save':
		if efe['kind']=='circle':
			centre=efe['content'][1]
			if map_kind=='bd':
				efe['content'][1]=bd09_to_wgs84(centre['lng'],centre['lat'])
			elif map_kind=='gd':
				efe['content'][1]=gcj02_to_wgs84(centre['lng'],centre['lat'])

		elif efe['kind'] in ['polygon','rectangle']:
			for y in range(len(efe['content'])):
				if map_kind=='bd':
					efe['content'][y]=bd09_to_wgs84(efe['content'][y]['lng'],efe['content'][y]['lat'])
				elif map_kind=='gd':
					efe['content'][y]=gcj02_to_wgs84(efe['content'][y]['lng'],efe['content'][y]['lat'])

	# print('new==========>',efe)
	return efe


# @login_required
@csrf_exempt
def efence(request):
	what=request.GET.get('what')
	map_kind=request.GET.get('map_kind')
	print(what,map_kind)

	if request.method=='GET':
		if what=='get_efence':
			subordinate_user=get_subordinate_user(request,Myuser)
			subordinate_user.append(str(request.user))
			efence_data=list(Efence.objects.filter(owner__in=subordinate_user).values())
			# print(efence_data)
			efence_data=handle_efence_by_mapkind(efence_data,map_kind)
			return HttpResponse(json.dumps(efence_data))

	if request.method=='POST':

		log_content='efence'+request.GET.get('what')
		system_log(request,log_content)

		if what=='add':
			efence_info=eval(request.POST.get('base_info'))
			check_efe_name=Efence.objects.filter(name=efence_info['name']).first()
			# print(check_efe_name)
			if check_efe_name!=None:
				return HttpResponse(json.dumps('围栏名称重复'))

			efence_info=handle_efence_by_mapkind(efence_info,map_kind,'save')
			# 存储在device表格efence字段的内容{efence:efence_to_dev}
			efence_to_dev=efence_info.copy()
			efence_to_dev.pop('device_id')
			efence_bind_dev=efence_info['device_id']
			efence_info['owner']=request.user
			efence_info['content']=str(efence_info['content'])
			efence_info['device_id']=str(efence_bind_dev)


			Efence.objects.create(**efence_info)

			for x in efence_bind_dev:
				efence=Device.objects.filter(device_id=x).first().efence
				if efence !='0':
					if isinstance(eval(efence),dict)==True:
						efence_detail=eval(efence)
						efence_detail[efence_info['name']]=efence_to_dev
						Device.objects.filter(device_id=x).update(efence=str(efence_detail))
					else:
						efence_detail={}
						efence_detail[efence_info['name']]=efence_to_dev
						Device.objects.filter(device_id=x).update(efence=str(efence_detail))

				else:
					efence_detail={}
					efence_detail[efence_info['name']]=efence_to_dev
					Device.objects.filter(device_id=x).update(efence=str(efence_detail))

			subordinate_user=get_subordinate_user(request,Myuser)
			subordinate_user.append(str(request.user))
			efence_data=list(Efence.objects.filter(owner__in=subordinate_user).values())

			return HttpResponse(json.dumps(efence_data))

		# 围栏信息修改
		elif what=='edit':
			efence_info=request.POST.get('base_info')
			efence_info= eval(efence_info)

			del_dev=efence_info.pop('del_dev')
			add_dev=efence_info.pop('add_dev')
			stay_dev=efence_info.pop('stay_dev')
			# 存储在dev的efence字段的围栏信息，不需要device_id列表
			new_bind_dev=str(efence_info.pop('device_id'))
			efe_name=efence_info['name']

			# 把解绑的dev里面的efence的相应内容去掉
			if del_dev!=[]:
				for x in del_dev:
					efence=Device.objects.filter(device_id=x).first()
					if efence!=None:
						efence=eval(efence.efence)
						efence.pop(efe_name)
						if efence=={}:
							efence='0'
						Device.objects.filter(device_id=x).update(efence=str(efence))

			# 把绑定围栏的dev的efence里面增加围栏内容
			if add_dev!=[]:
				for x in add_dev:
					efence=Device.objects.filter(device_id=x).first()
					if efence!=None:
						efence=efence.efence
						if efence !='0':
							efence=eval(efence)
							efence[efe_name]=efence_info
							Device.objects.filter(device_id=x).update(efence=str(efence))
						else:
							efence={}
							efence[efe_name]=efence_info
							Device.objects.filter(device_id=x).update(efence=str(efence))

			# 不变的dev，更新相应围栏的内容
			if stay_dev!=[]:
				for x in stay_dev:
					efence=Device.objects.filter(device_id=x).first()
					if efence!=None:
						efence=eval(efence.efence)
						if isinstance(efence,dict)==True:
							for y in efence:
								if y==efe_name:
									efence[efe_name].update(efence_info)
									Device.objects.filter(device_id=x).update(efence=str(efence))
						else:
							new_bind_dev=eval(new_bind_dev)
							new_bind_dev.remove(x)
							new_bind_dev=str(new_bind_dev)



			# 更新围栏列表里面的内容，存储在围栏变革里面的围栏数据，包含绑定的device_id列表

			efence_info['device_id']=new_bind_dev
			Efence.objects.filter(name=efe_name).update(**(efence_info))

			subordinate_user=get_subordinate_user(request,Myuser)
			subordinate_user.append(str(request.user))
			efence_data=list(Efence.objects.filter(owner__in=subordinate_user).values())

			return HttpResponse(json.dumps(efence_data))



	return render(request,'tracker_app/efence.html')


def other_efence_set(request):
	return render(request,'tracker_app/other_efence_set.html')

# 车辆运行统计
# @login_required
@csrf_exempt
def mileage_reports(request):
	return render(request,'tracker_app/mileage_reports.html')

# 人员报警统计
@csrf_exempt
def alarm_reports(request):

	if request.method=='POST':
		if request.GET.get('what')=='alarm_reports':
			query_param=eval(request.POST.get('query_param'))
			device_ids=query_param['hard_id']
			s_time=query_param['s_time']
			e_time=query_param['e_time']
			reports_data=[]
			
			for device_id in device_ids:
				filed_dict={'speed_alarm':list(),'efence':list(),'stop_alarm':list(),'polyline':list(),'sos_alarm':list()}
				repo_data={}
				filed_dict['device_id']=device_id
				alarm_detail=Alarm.objects.filter(device_id=device_id).filter(s_time__lt=e_time).filter(s_time__gt=s_time).values()

				if alarm_detail.first()!=None:

					for x in alarm_detail:

						if x['kind'] in filed_dict:
							filed_dict[x['kind']].append(x)

					reports_data.append(filed_dict)

			return HttpResponse(json.dumps(reports_data))

		elif request.GET.get('what')=='health_alarm_reports':
			system_log(request,'health_alarm_reports')
			query_param=eval(request.POST.get('query_param'))
			device_ids=query_param['hard_id']
			s_time=query_param['s_time']
			e_time=query_param['e_time']
			reports_data=[]
			
			for device_id in device_ids:
				filed_dict={'heart_alarm':list(),'efence':list(),'stop_alarm':list(),'blood_alarm':list(),
							'sos_alarm':list(),'fall_down':list(),'heart_high':list(),'heart_low':list(),
							'l_pres_heig':list(),'l_pres_low':list(),'h_pres_heig':list(),'h_pres_low':list(),
							'polygon':list(),'rectangle':list(),'circle':list()}
				repo_data={}
				filed_dict['device_id']=device_id
				alarm_detail=Alarm.objects.filter(device_id=device_id).filter(s_time__lt=e_time).filter(s_time__gt=s_time).values()

				if alarm_detail.first()!=None:

					for x in alarm_detail:

						if x['kind'] in filed_dict:
							filed_dict[x['kind']].append(x)

				reports_data.append(filed_dict)

			return HttpResponse(json.dumps(reports_data))

	return render(request,'tracker_app/alarm_reports.html')


@csrf_exempt
def health_reports(request):
	what=request.GET.get('what')
	if request.method=='GET':
		if what=='get_health_reports':
			subordinate_user=get_subordinate_user(request,Myuser)
			subordinate_user.append(str(request.user))
			dev_id_list=Device.objects.filter(owner__in=subordinate_user).values('device_id')
			dev_id_list=pd.DataFrame(dev_id_list)
			dev_id_list=dev_id_list['device_id'].tolist()
			# print(dev_id_list)
			# 服务器的默认时区与中国时区相差16小时？？有待观察
			now = time.time()
			midnight = now - (now % 86400) + time.timezone
			# print(datetime.datetime.strptime(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(now)), "%Y-%m-%d %H:%M:%S"))
			pre_midnight = midnight - 86400
			now_midnight = midnight - 1
			s_time = datetime.datetime.strptime(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(pre_midnight)), "%Y-%m-%d %H:%M:%S")
			s_time=str(s_time)

			reports=Daily_Report.objects.filter(device_id__in=dev_id_list).filter(analysis_time=s_time).values()
			reports=list(reports)

			return HttpResponse(json.dumps(reports))


	if request.method=='POST':
		if what=='health_reports':
			system_log(request,'health_reports')
			query_param=eval(request.POST.get('query_param'))
			device_ids=query_param['hard_id']
			s_time=query_param['s_time']
			e_time=query_param['e_time']
			chose_time=query_param['chose_time']
			if chose_time!='0':
				now = time.time()
				midnight = now - (now % 86400) + time.timezone
				s_time = midnight - 86400*int(chose_time)
				s_time = datetime.datetime.strptime(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(s_time)), "%Y-%m-%d %H:%M:%S")
				s_time=str(s_time)
				print(s_time,e_time)
			reports_data=[]
			reports_detail={}
			for device_id in device_ids:
				refresh_session(device_id)
				if chose_time=='1':
					repo_data=start_cacu(device_id)
				else:
					repo_data=start_cacu(device_id,s_time,e_time)
				repo_data['device_id']=device_id
				reports_data.append(repo_data)
				
			# print(json.dumps(reports_data))
			return HttpResponse(json.dumps(reports_data))


	return render(request,'tracker_app/health_reports.html')


@csrf_exempt
def trackmap_inroom(request):
	return render(request,'tracker_app/trackmap_inroom.html')

# 注册
@csrf_exempt
def pc_register(request):
	key = request.GET.get('key', "")
	print(key)
	res = BaseResponse()
	if request.method=='POST':
		if key == 'validation':
			phone = request.POST.get('phone','')
			if phone:
				user_obj = Myuser.objects.filter(username=phone).first()
				if user_obj:
					res.code = 1024
					res.error = "该手机号已注册"
					return HttpResponse(json.dumps(res.dict))
				elif len(phone) > 11 or len(phone) < 11:
					res.code = 1024
					res.error = "请输入正确的手机号"
					return HttpResponse(json.dumps(res.dict))
				else:
					verification_code = str(random.randint(100000,999999))
					now_time = str(int(time.time()))
					# print(verification_code,phone,now_time)
					sms = send_sms(verification_code,phone,now_time)#发送短信
					res.code=1000
					res.data = "发送成功"
					mesg_redis.set(phone,verification_code,ex=600)
					return HttpResponse(json.dumps(res.dict))
			else:
				res.code = 1024
				res.error = "请携带手机号"
				return HttpResponse(json.dumps(res.dict))
		elif key == 'registered':
			phone = request.POST.get('phone','')
			password = request.POST.get('password','')
			validation = request.POST.get('v_code','')
			visible_name = request.POST.get('nickname','')
			if visible_name=='':
				visible_name=phone
			if phone and password and validation:
				user_obj = Myuser.objects.filter(username=phone).first()
				if user_obj:
					res.code = 1024
					res.error = "该手机号已注册"
					return HttpResponse(json.dumps(res.dict))
				else:
					verification_code = mesg_redis.get(phone)
					if verification_code==None:
						res.code = 1024
						res.error = "验证码已过期，请重新获取"
						return HttpResponse(json.dumps(res.dict))
					else:
						if verification_code == validation:
							Myuser.objects.create(
									username=phone, visible_name=visible_name,level='0',
									email='0', leader='0', status='on',
									subordinate="0",character="{'password':"+password+",'kind':'phone_user','user_icon':'/static/img/default.png','refresh_time':'60','alarm_audio':'on','alarm_show':'on','handle_device':'no'}",remark='0')
							res.data = "注册成功"
							User.objects.create_user(username=phone,password=password)
							res.code=1000
							return HttpResponse(json.dumps(res.dict))
						else:
							res.code = 1024
							res.error = "验证码错误"
							return HttpResponse(json.dumps(res.dict))
			else:
				res.code = 1024
				res.error = "请携带参数"
				return HttpResponse(json.dumps(res.dict))
		else:
			res.code = 1024
			res.error = "请携带参数"
			return HttpResponse(json.dumps(res.dict))

	return render(request,'tracker_app/reg.html')

# 重置密码
@csrf_exempt
def forgot_pwd(request):
	key = request.GET.get('key', "")
	print(key)
	res = BaseResponse()
	if request.method=='POST':
		if key == 'validation':
			phone = request.POST.get('phone','')
			if phone:
				user_obj = Myuser.objects.filter(username=phone).first()
				if user_obj:
					verification_code = str(random.randint(100000,999999))
					now_time = str(int(time.time()))
					# print(verification_code,phone,now_time)
					sms = send_sms(verification_code,phone,now_time)#发送短信
					res.code=1000
					res.data = "发送成功"
					mesg_redis.set(phone,verification_code,ex=600)
					return HttpResponse(json.dumps(res.dict))
				else:
					res.code = 1024
					res.error = "该手机号尚未注册"
					return HttpResponse(json.dumps(res.dict))
			else:
				res.code = 1024
				res.error = "请携带手机号"
				return HttpResponse(json.dumps(res.dict))
		elif key == 'reset_pwd':
			phone = request.POST.get('phone','')
			password = request.POST.get('password','')
			validation = request.POST.get('v_code','')
			if phone and password and validation:
				verification_code = mesg_redis.get(phone)
				if verification_code==None:
					res.code = 1024
					res.error = "验证码已过期，请重新获取"
					return HttpResponse(json.dumps(res.dict))
				else:
					if verification_code == validation:
						user = User.objects.get(username=phone)
						if user is not None:
							user.set_password(password)
							user.save()
							res.code=1000
							res.data='重置密码成功'
							return HttpResponse(json.dumps(res.dict))
						else:
							res.code = 1024
							res.error = "无此用户，重置密码失败"
							return HttpResponse(json.dumps(res.dict))
						
					else:
						res.code = 1024
						res.error = "验证码错误"
						return HttpResponse(json.dumps(res.dict))
			else:
				res.code = 1024
				res.error = "请携带参数"
				return HttpResponse(json.dumps(res.dict))
		else:
			res.code = 1024
			res.error = "请携带参数"
			return HttpResponse(json.dumps(res.dict))

	return render(request,'tracker_app/forget.html')


#其他调用模块

def latLng2WebMercator(lng, lat):#WGS85转墨卡托坐标系，蜂鸟地图用
	earthRad = 6378137
	x = lng * pi / 180 * earthRad
	a = lat * pi / 180
	y = earthRad / 2 * math.log((1.0 + sin(a)) / (1.0 - sin(a)))
	return x, y



EARTH_REDIUS = 6378.137

def rad(d):
	return d * pi / 180.0

def getDistance(lat1, lng1, lat2, lng2):
	radLat1 = rad(lat1)
	radLat2 = rad(lat2)
	a = radLat1 - radLat2
	b = rad(lng1) - rad(lng2)
	s = 2 * math.asin(math.sqrt(math.pow(sin(a/2), 2) + cos(radLat1) * cos(radLat2) * math.pow(sin(b/2), 2)))
	s = s * EARTH_REDIUS
	return s


def getmodelfield(appname,modelname,exclude):
	modelobj = apps.get_model(appname, modelname)
	filed = modelobj._meta.fields
	fielddic = []
	#fielddic=collections.OrderedDict()
	params = [f for f in filed if f.name not in exclude]
	for i in params:
		fielddic.append(i.name+':'+i.verbose_name)

	return fielddic



#命令下发调用
import socket
import os,sys
import re
# print(sys.stdout.encoding)

def log_write(data):#日志log存储
	with open('data_handle/sys_log/import_command_log','a') as f:
		f.write(data)
		f.write('&&')
#自动加载command文件夹里面的所有command命令文档，存储为字典{厂家型号：命令函数（）}，
#例如{'vk':lambda device_id,kind,param,model:vk_command(device_id,kind,param,model)}
command={}
def impfile(filename):
	filelist,*_ = os.walk(filename,topdown=True)
	*_,filenames = filelist
	for i in filenames:
		# print(i)
		if i[-3:] == '.py' and i != '__init__.py':
			try:
				device_model=re.search(r'(?P<model>\w*)_',i).group('model')
				exc = 'from '+ 'data_handle.command'+'.'+i[:-3] + ' import '+ i[:-3]
				exec(exc,globals())
				# command[device_model]=lambda device_id,kind,param,model:eval(i[:-3])(device_id,kind,param,model)
				command[device_model]=i[:-3]
			except Exception as e:
				log_data=str([i,e,datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')])
				log_write(log_data)
#命令函数目录名
impfile('data_handle/command')
print(command)
#调用命令函数，，下发指令，指令存储在redis，连接twisted的时候，触发接收redis指令内容，下发。
def set_param(model,imei,commd,value,sender='admin'):
	device_model=model[1]
	port=model[0]
	server_reply=''
	if device_model in command:
		param=eval(command[device_model]+'(imei,commd,value,device_model,sender)')
		print(param)
		if param=='':
			return 'unsupport command'
		params=str([imei,param,commd])
		ip_port = ('localhost',port)
		sk = socket.socket()
		mesg_redis.lpush('set_param',params)
		sk_res=sk.connect_ex(ip_port)
		# print('sk_res====>',sk_res)
		if sk_res!=0:
			server_reply=sk_res
			return sk_res
		server_reply = sk.recv(1024)
		server_reply = server_reply.decode()
		print(server_reply)
		sk.close()
	else:
		log_write(str([imei,device_model,'command file not found!']))
		server_reply='command file not found!'

	return server_reply


def get_device_detail(subordinate_user,map_kind='bd'):
	# 读取该用户和下属用户的所有设备信息
	sql_device = 'select * from tracker_app_device'
	device = pd.read_sql_query(sql_device,engine)
	# 判断是否有device
	if device.shape[0]>0:
		# 判断该用户名下是否有设备
		device_data=device.loc[(device['owner'].isin(subordinate_user)) & (device['dynamic']!='0')].copy()
		if device_data.shape[0]>0:
			device_data=handle_dynamic_data(device_data,map_kind)
			return device_data
	return []

def handle_dynamic_data(device_data,map_kind):
	# 设备的使用者信息，字符串转换为字典
	def hanle_user_detail(data):
		if data=='' or data=='0' or data==0 :
			data={"customize_title1":"","customize_title2":"","customize_title3":"","customize_value1":"","customize_value2":"","customize_value3":"","icon":"default"}
		else:
			data=eval(data)
		return data
	device_data['user_detail']=device_data['user_detail'].map(lambda x:hanle_user_detail(x))
	# device_data['user_detail']=device_data['user_detail'].map(lambda x:x['current'] if isinstance(x,dict)==True else x)
	# 设备的参数设置信息，字符串转换为字典
	device_data['param_set']=device_data['param_set'].map(lambda x:eval(x))
	# 设备的最新更新信息进行处理,字符串转换为字典,位置,在线状态,报警状态,设备自身状态等进行处理
	device_data['dynamic']=device_data['dynamic'].map(lambda x:eval(x))
	# 位置信息
	# 1、卫星定位
	device_data.loc[:,'lng']=device_data['dynamic'].map(lambda x:x['lng'])
	device_data.loc[:,'lat']=device_data['dynamic'].map(lambda x:x['lat'])
	# 2、lbs定位，wifi定位
	# def get_address_from_wifilbs(wifi_lbs,track_type):
	# 	wifi_lbs=eval(wifi_lbs)
	# 	for x in wifi_lbs:
	# 		result=''
	# 		if track_type=='wifi':
	# 			result=get_wifi_address(x,'yes')
	# 		elif track_type=='lbs':
	# 			result=get_lbs_address(x,'yes')
	# 		if result[0]!='0' and result[1]!='0':
	# 			return result
	# 			break
	# 	return ('0','0')
	device_data.loc[:,'wifi_address']=device_data['dynamic'].map(lambda x:get_wifi_address(x['wifi'],x['device_id']) if x['track_type']=='wifi' else '0')
	device_data['lng']=device_data.apply(lambda x:float(x['wifi_address'][0]) if x['dynamic']['track_type']=='wifi' and x['wifi_address'][0]!='0' else x['lng'],axis=1)
	device_data['lat']=device_data.apply(lambda x:float(x['wifi_address'][1]) if x['dynamic']['track_type']=='wifi' and x['wifi_address'][1]!='0'else x['lat'],axis=1)
	device_data.loc[:,'lbs_address']=device_data['dynamic'].map(lambda x:get_lbs_address(x['lbs'],x['device_id']) if x['track_type']=='lbs' else '0')
	device_data['lng']=device_data.apply(lambda x:float(x['lbs_address'][0]) if x['dynamic']['track_type']=='lbs' else x['lng'],axis=1)
	device_data['lat']=device_data.apply(lambda x:float(x['lbs_address'][1]) if x['dynamic']['track_type']=='lbs' else x['lat'],axis=1)
	# 坐标系转换bd:百度,gd:高德
	if map_kind=='bd':
		device_data.loc[:,'change_lnglat']=device_data.apply(lambda x:wgs84_to_bd09(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
	elif map_kind=='gd':
		device_data.loc[:,'change_lnglat']=device_data.apply(lambda x:wgs84_to_gcj02(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
	# print(device_data['change_lnglat'])
	device_data['lng']=device_data.apply(lambda x:x['change_lnglat']['lng'] if x['change_lnglat']!='0' else x['lng'],axis=1)
	device_data['lat']=device_data.apply(lambda x:x['change_lnglat']['lat'] if x['change_lnglat']!='0' else x['lat'],axis=1)
	

	# 在线状态，在线，离线，休眠
	now=int(time.time())

	device_data['serv_receive']=device_data['dynamic'].map(lambda x:'2000-01-01 01:01:01' if x['serv_receive']=='0' else x['serv_receive'])
	device_data.loc[:,'on_off_line']=device_data['dynamic'].map(lambda x:x['on_off_line'] if x.get('on_off_line')!=None else 'offline')
	# 超过15分钟没数据，判断为离线,因为部分设备链接断开也不会提示
	device_data['on_off_line']=device_data.apply(lambda x:'offline' if x['on_off_line']=='online' and now-time.mktime(time.strptime(x['serv_receive'],'%Y-%m-%d %H:%M:%S'))>900 else x['on_off_line'],axis=1)
	# 在线，且超过数据发送间隔超过300秒，视为休眠
	device_data['sleep_status']=device_data.apply(lambda x:'sleep' if x['on_off_line']=='online' and now-time.mktime(time.strptime(x['serv_receive'],'%Y-%m-%d %H:%M:%S'))>300 else 'no',axis=1)
	# 设备状态，acc，定位与否等
	device_data['status']=device_data['status'].map(lambda x:eval(x) if x!='0' else [])
	device_data.apply(lambda x:x['status'].append(x['on_off_line']),axis=1)
	device_data.apply(lambda x:x['status'].append(x['sleep_status']) if x['sleep_status']!='no' else None,axis=1)
	# 报警状态，需要读取数据库，数据库读取的效率大概为1000次/秒，数量大了影响速度，以后改进
	device_data.loc[:,'alarm_status']=device_data['device_id'].map(lambda x:'alarm' if Alarm.objects.filter(device_id=x).filter(handle='no').first()!=None else 'no')
	# device_data['iccid']=device_data['iccid'].map(lambda x:str(x))
	# 电量、rssi信号
	device_data.loc[:,'battery']=device_data['dynamic'].map(lambda x:x['battery'])
	device_data.loc[:,'rssi']=device_data['dynamic'].map(lambda x:x['rssi'])
	device_data=device_data.drop(['change_lnglat'], axis=1)
	# device_data=device_data.drop(['dynamic','wifi_address','lbs_address','change_lnglat'], axis=1)
	# user_device=device_data.groupby('owner')['owner'].count()
	# print('user_device====>',user_device)
	device_data=json.loads(device_data.to_json(orient="records",force_ascii=False))

	return device_data



def get_user_tree(user,Myuser,user_tree,subordinate_user):
	print(user)
	user_datail=Myuser.objects.filter(username=user).first()
	if user_datail!=None:
		visible_name=user_datail.visible_name
		level=user_datail.subordinate
		user_id=user_datail.id
		sub_data={"id":user_id,'name':user,"title":visible_name, "children":[],'spread':'true'}
		user_tree.append(sub_data)

		if level!='0':
			level=level.split(',')
			for x in level:
				subordinate_user.append(x)
				get_user_tree(x,Myuser,user_tree[-1]['children'],subordinate_user)


def get_subordinate_user(request,Myuser):
	user_tree=[]
	# 下级用户列表
	subordinate_user=[]
	# 本次请求的用户名
	user=str(request.user)
	# 获取用户的树状结构信息，并把下级用户信息加入subordinate_user列表
	get_user_tree(user,Myuser,user_tree,subordinate_user)
	# 获取下级用户信息
	return subordinate_user

def store_picture(base64data,folder_name,device_id):

	# print(folder_name)
	# print(device_id)
	param_data=base64data.split(',')[1]
	img = base64.b64decode(param_data)
	file_folder={'person':'person/','car':'car/','building':'building/','map':'map/','scanner':'scanner/'}
	# 创建路径，有的话不用理会
	sys_platform=sys.platform[0:3]
	try:
		path=''
		if sys_platform=='win':
			path='E:\\tracker\\tracker_app\\static\\data_from_web\\picture\\'+folder_name+'\\'
		else:
			path='/root/tracker/tracker_app/static/data_from_web/user/'+str(request.user)
		os.makedirs(path)
	except:
		pass

	img_name=''
	if sys_platform=='win':
		img_name='tracker_app/static/data_from_web/picture/'+file_folder[folder_name]+device_id+'_picture.png'
	else:
		img_name='/root/tracker/tracker_app/static/data_from_web/picture/'+file_folder[folder_name]+device_id+'_picture.png'
	
	# print(img_name,type(img_name))
	fh = open(img_name,"wb")
	fh.write(img)
	fh.close()
	src_path='/static/data_from_web/picture/'+file_folder[folder_name]+device_id+'_picture.png'
	return src_path


def get_lbs_address(lbs_data,device_id,only_from_db='no'):
	lbs_data=eval(lbs_data)
	all_lbs=[]
	for x in lbs_data:
		lbs=x['MCC']+','+x['MNC']+','+x['sid']+','+x['nid']+','+str(x['rssi'])
		all_lbs.append(lbs)
	bts_lbs=all_lbs[0]
	all_lbs='|'.join(all_lbs)
	lbs_lng='0'
	lbs_lat='0'
	zh_address='0'
	lbs_accuracy='0'
	mcc=lbs_data[0]['MCC']
	mnc=lbs_data[0]['MNC']
	lbs_nid=lbs_data[0]['nid']
	lbs_sid=lbs_data[0]['sid']
	lbs_mac=lbs_sid+lbs_nid
	lbs_address=WIFI_LBS_ADDR.objects.filter(mac=lbs_mac).first()
	# print('all_lbs=======>',all_lbs)
	if lbs_address==None and only_from_db=='no':

		print(only_from_db)
		# get_lbs='http://api.cellocation.com:81/cell/?mcc='+mcc+'&mnc='+mnc+'&lac='+lbs_sid+'&ci='+lbs_nid+'&output=json'
		get_lbs='http://apilocate.amap.com/position?accesstype=0&imei='+device_id+'&cdma=0&bts='+bts_lbs+'&'+all_lbs+'&key=0ff8329afe2ab4e379f6af1f555c86b7'
		lbs_loca=requests.get(get_lbs)
		lbs_loca=eval(lbs_loca.text)
		if lbs_loca.get('info')=='OK' and lbs_loca.get('status')=='1':
			response_result=lbs_loca['result']
			if response_result.get('location')!=None:
				lnglat=response_result['location'].split(',')
				# 获取的是高德地图的的接口，得到的数据为gcj02的经纬度，此处转为原始的wgs84
				change_l=gcj02_to_wgs84(float(lnglat[0]),float(lnglat[1]))
				lbs_lng=change_l['lng']
				lbs_lat=change_l['lat']
				lbs_accuracy=response_result['radius']
				zh_address=response_result['desc']
				try:
					WIFI_LBS_ADDR.objects.create(mac=lbs_mac,ssid=str([mcc,mnc]),rssi=lbs_data[0]['rssi'],lng=lbs_lng,lat=lbs_lat,kind='lbs',
												location=str(response_result))
				except Exception as e:
					raise
	elif lbs_address!=None:

		lbs_lng=lbs_address.lng
		lbs_lat=lbs_address.lat
		zh_address=lbs_address.location

	return lbs_lng,lbs_lat,zh_address

def get_wifi_address(wifi_data,device_id,only_from_db='no'):
	# print(wifi_data)
	wifi_data=eval(wifi_data)
	all_mac=[]
	repeat_mac=[]
	# 去掉重复
	for x in wifi_data:
		if x['mac'] not in repeat_mac:
			mac=x['mac']+','+str(x['rssi'])
			all_mac.append(mac)
			repeat_mac.append(x['mac'])
	# 高德的wifi接口，必须2个wifi mac以上才有地址
	if len(all_mac)==1:
		all_mac='0'
	else:
		all_mac='|'.join(all_mac)
	f_wifi_mac=wifi_data[0]['mac']
	wifi_ssid=wifi_data[0]['ssid']
	wifi_rssi=wifi_data[0]['rssi']
	wifi_lng='0'
	wifi_lat='0'
	zh_address='0'
	wifi_accuracy='0'
	wifi_address=WIFI_LBS_ADDR.objects.filter(mac=f_wifi_mac).first()
	def get_address(save_kind):
		print(only_from_db)
		get_url='http://apilocate.amap.com/position?accesstype=1&imei='+device_id+'&macs='+all_mac+'&key=0ff8329afe2ab4e379f6af1f555c86b7'
		# print(get_url)
		# print(wifi_data)
		wifi_loca=requests.get(get_url)
		wifi_loca=eval(wifi_loca.text)
		# print('wifi_loca====>',wifi_loca)
		if wifi_loca.get('info')=='OK' and wifi_loca.get('status')=='1':
			response_result=wifi_loca['result']
			if response_result.get('location')!=None:
				lnglat=response_result['location'].split(',')
				# 获取的是高德地图的wifi转lnglat的接口，得到的数据为gcj02的经纬度，此处转为原始的wgs84
				change_l=gcj02_to_wgs84(float(lnglat[0]),float(lnglat[1]))
				wifi_lng=change_l['lng']
				wifi_lat=change_l['lat']
				wifi_accuracy=response_result['radius']
				zh_address=response_result['desc']
				if save_kind=='save':
					WIFI_LBS_ADDR.objects.create(mac=f_wifi_mac,ssid=wifi_ssid,rssi=wifi_rssi,lng=wifi_lng,lat=wifi_lat,kind='wifi',
												location=str(response_result))
				elif save_kind=='update':
					WIFI_LBS_ADDR.objects.filter(mac=f_wifi_mac).update(ssid=wifi_ssid,sid='0',nid='0',mcc='0',mnc='0',rssi=wifi_rssi,lng=wifi_lng,lat=wifi_lat,kind='wifi',
																	location=str(response_result),date_added=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
					# session.update(WIFI_LBS_ADDR(mac=f_wifi_mac,))
				session.commit()
			else:
				if save_kind=='save':
					WIFI_LBS_ADDR.objects.create(mac=f_wifi_mac,ssid=wifi_ssid,sid='0',nid='0',mcc='0',mnc='0',rssi=wifi_rssi,lng='0',lat='0',kind='wifi',
													location=str(wifi_data),date_added=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
					session.commit()

	# wifi地址没有存库的情况下，通过接口获取的数据，分为有经纬度和无经纬度两种，有经纬度的在location存储具体的返回信息，没有经纬度的存储原来的wifi数据
	if wifi_address==None and only_from_db=='no' and all_mac!='0' :
		get_address('save')
		
	# wifi地址有存库，但是存储的经纬度为零，并且新请求的wifi数据与原先存储的wifi数据不一样的是，可以再次进行wifi转地址的接口请求
	elif wifi_address!=None :
		if str(wifi_data)!=wifi_address.location and wifi_address.lng=='0':
			get_address('update')
		else:
			wifi_lng=wifi_address.lng
			wifi_lat=wifi_address.lat
			zh_address=wifi_address.location
					
	return wifi_lng,wifi_lat,zh_address


# 手机端数据接口，以及第三方数据接口

class BaseResponse(object):
	def __init__(self):
		self.code = 1000  # 这是成功的数字
		self.error = None  # 报错信息
		self.data = None  # 返回的数据

	@property
	def dict(self):
		return self.__dict__  # 获取这个类里的所有数据

# 从token取用户名
def get_username_from_token(request):
	token = request.META.get("HTTP_AUTHORIZATION", "")
	user_id=mesg_redis.get(token)
	username=Myuser.objects.get(id=user_id).username
	return user_id,username


def get_device_tree(user,Myuser,dev_tree,device_data):
	user_datail=Myuser.objects.filter(username=user).first()
	visible_name=user_datail.visible_name
	level=user_datail.subordinate
	user_id=user_datail.id
	device_data=pd.DataFrame(device_data)
	device_data.loc[:,'title']=device_data['user_name']
	device_belong=json.loads(device_data.loc[device_data['owner']==user].to_json(orient="records",force_ascii=False))
	sub_data={"id":user_id,'name':user,"title":visible_name, "children":device_belong,'spread':'true','kind':'tree_title'}
	dev_tree.append(sub_data)

	if level!='0':
		level=level.split(',')
		for x in level:
			get_device_tree(x,Myuser,dev_tree[-1]['children'],device_data)
	else:
		return


from data_handle.change_lnglat import *

def login_func(res,request):

	# print("user", user)
	user = request.data.get("user", None)
	if user is None:
		res['error'] = "未携带用户名和密码"
		res['code'] = 1010

	if user:
		username = user.get("username", "")
		password = user.get("password", "")
		if username and password != "":
			user_obj = authenticate(username=username, password=password)
			# print(user_obj)
			if user_obj is not None:
				# 查看是否是停用账户
				user_detail=Myuser.objects.filter(username=username).first()
				if user_detail.status == "off":
					res.code = 10234
					res.error = "此账号已被停用,请确认之后登录"
				# 记录日志
				now1 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
				request.user=username
				system_log(request,'username','success')
				token1 = uuid.uuid4()
				token = str(token1)
				# 将用户id以及token值存入redis,并且设置有效期为7天
				user_id = user_detail.id
				mesg_redis.set(token, user_id, ex=datetime.timedelta(days=7))
				# 获取此用户的权限
				# 暂时给空值
				role=user_detail.character
				ret_all_dic={}
				res.data = {"token": token, "username": username, "role": role, "permission": ret_all_dic}
			else:
				# 用户密码校验不成功
				res.error = "用户名或密码错误"
				res.code = 1011
	else:
		res.error = "未携带用户名和密码"
		res.code = 1010

	return res



class LoginView(APIView):

	def post(self, request):
		res = BaseResponse()

		"""
		前端接收用户名跟密码
		到数据库中校验用户名跟密码
		校验通过将成功信息返回给前端
		{
			"user":{
				"username":"hanlei",
				"password":"hanleilei"
			}
		}
		"""
		result=login_func(res,request)
		print(result)
		return Response(result.dict)


class BaseInfo(APIView):
	"""GPS设备实时定位,系统高频使用的静态数据，设备基本信息，报警等"""

	def options(self,request):
		print('options========>',dir(request))
		key = request.query_params.get('key', "")
		param_data=request.data.get('param_data')
		print(key,param_data)
		method = request.META.get('Access_Control_Allow_Method')
		origin = request.META.get('Origin')
		response = Response()
		response['charset']='utr-8'
		response['Content-Type']='application/json'
		response['Access-Control-Allow-Credentials'] ='true'
		response['Access_Control_Allow_Method'] = "POST,GET,OPTIONS"  # 支持那些请求方法，可以根据实际情况配置如 "POST, GET ,OPTIONS"
		response['Access-Control-Allow-Origin'] = '*'  # 实际操作中本人无法获取请求头中的Origin参数，所以这里我实际上是配置成了 "*",但是不建议这样操作,后续会有问题,可以根据实际情况写成固定的也可以 "完整域名"
		response["Access-Control-Allow-Headers"] = "X-CSRFToken, Content-Type,authorization,key,map" # 如果配置接收的请求头有遗漏，当发送OPTIONS方法成功后，发送正式请求时将会在浏览器报错，可以根据浏览器中consolo的报错内容添加进去即可, 我这里需要配置的就是这两个
		print(response,method)
		return response
	def get(self, request):
		"""
		根据携带的key,来区分是人员,还是车辆,还是全部都要
		key=car, key=person, key=all
		"""
		res = BaseResponse()

		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		username=Myuser.objects.get(id=user_id).username
		request.user=username
		user_id=mesg_redis.get(token)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		key = request.query_params.get('key', "")
		print(key)


		if key=='all':
			map_kind = request.META.get("HTTP_MAP", "")  # 请求的是什么地图
			if not map_kind:
				res.error = "请携带地图参数"
				res.code = 1208
				return Response(res.dict)

			user_tree=[]
			# 下级用户列表
			subordinate_user=[]
			# 本次请求的用户名
			user=str(request.user)
			# 获取用户的树状结构信息，并把下级用户信息加入subordinate_user列表
			get_user_tree(user,Myuser,user_tree,subordinate_user)
			# 获取下级用户信息
			user_data=list(Myuser.objects.all().filter(username__in=subordinate_user).values())
			# 获取用户自身的信息
			user_self=Myuser.objects.get(username=user)
			user_self=vars(user_self)
			user_self.pop('_state')
			user_self['character']=eval(user_self['character'])
			# 获取用户和下级用户名下所有的设备信息
			subordinate_user.append(user)
			device=get_dev_by_userkind(user_self['character'],subordinate_user,'gd')
			alarm_data=get_alarm_by_userkind(user_self['character'],subordinate_user)
			device_tree=[]
			if len(device)!=0:
				get_device_tree(user,Myuser,device_tree,device)

			all_data={"device_tree": device_tree,'user_self':user_self,'alarm_data':alarm_data,'all_device':device}
			res.code=1000
			res.data = all_data
			return Response(res.dict)
		else:
			res.code = 1023
			res.error = "请携带参数"
			return Response(res.dict)

	def post(self, request):
		res = BaseResponse()
		key = request.query_params.get('key', "")
		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		username=Myuser.objects.get(id=user_id).username
		request.user=username
		# print('key======>',key)
		# print('request.user======>',request.user)


		if key=='tracking':
			map_kind = request.META.get("HTTP_MAP", "")  # 请求的是什么地图
			if not map_kind:
				res.error = "请携带地图参数"
				res.code = 1208
				return Response(res.dict)

			device_id = request.data.get('device_id')

			dev_table=Device_Base.classes[device_id]
			dev_newest=session.query(dev_table).order_by(dev_table.id.desc()).first()

			old_data=mesg_redis.get('tracking'+device_id)
			if old_data==str(dev_newest.id):
				res.data='no_change'
				return Response(res.dict)
			dev_newest=vars(dev_newest)
			dev_newest.pop('_sa_instance_state')
			# print(dev_newest)
			if dev_newest['lng']=='0' and dev_newest['lat']=='0':
				result=['0','0']
				if dev_newest['wifi']!='0':
					result=get_wifi_address(dev_newest['wifi'],dev_newest['device_id'])
				elif dev_newest['lbs']!='0':
					result=get_lbs_address(dev_newest['lbs'],dev_newest['device_id'])

				dev_newest['lng']=result[0]
				dev_newest['lat']=result[1]

			change_lnglat=''
			if map_kind=='gd':
				change_lnglat=wgs84_to_gcj02(float(dev_newest['lng']),float(dev_newest['lat']))
			elif map_kind=='bd':
				change_lnglat=wgs84_to_bd09(float(dev_newest['lng']),float(dev_newest['lat']))
			dev_newest['lng']=change_lnglat['lng']
			dev_newest['lat']=change_lnglat['lat']
			if dev_newest['lng']==0:
				res.data='no_change'
				return Response(res.dict)

			res.data=dev_newest
			mesg_redis.set('tracking'+device_id,str(dev_newest['id']),ex=600)
	
			return Response(res.dict)

		elif key=='refresh_one_dev':

			device_id = request.data.get('device_id')

			# dev_table=Device_Base.classes[device_id]
			# dev_newest=session.query(dev_table).order_by(dev_table.id.desc()).first()
			# dev_newest=vars(dev_newest)
			# dev_newest.pop('_sa_instance_state')
			dev_newest=Device.objects.filter(device_id=device_id).first()
			if dev_newest!=None:
				dev_newest=vars(dev_newest)
				# print(dev_newest)
				dev_newest.pop('_state')
				dev_newest['dynamic']=eval(dev_newest['dynamic'])
			media=Multi_Media.objects.filter(sender=device_id).order_by('-id').first()
			picture=media.content
			send_time=media.send_time

			res.data={'device':dev_newest,'picture':picture,'send_time':send_time}
			# print(res.dict)

			return Response(res.dict)

		elif key=='get_wifi_lbs_addr':
			param_data=request.data.get('param_data')
			track_type=param_data.get('track_type')
			device_id=param_data.get('device_id')
			track_data=param_data.get('track_data')
			# dev_dynamic=Device.objects.get(device_id=device_id)
			# address_result=''
			# if dev_dynamic!=None:
			# 	dev_dynamic=eval(dev_dynamic.dynamic)
			# 	dev_wifi=eval(dev_dynamic[track_type])
			address_result=eval('get_'+track_type+'_address('+track_data+','+device_id+')')


			# print('address=====',address_result)
			address='0'
			if address_result!='':
				loca=address_result[2]
				if isinstance(loca,dict):
					loca=loca['desc']
				else:
					loca=eval(loca)
					loca=loca['desc']
				lnglat=wgs84_to_gcj02(float(address_result[0]),float(address_result[1]))
				address={'lng':lnglat['lng'],'lat':lnglat['lat'],'location':loca}
			res.data =address
			
			return Response(res.dict)

		if key=='alarm_set':
			param_data=request.data.get('param_data')
			device_id=param_data.pop('device_id')
			dev_data=Device.objects.get(device_id=device_id)
			if dev_data!=None:
				param_set=dev_data.param_set
				if param_set!='0':
					param_set=eval(param_set)
					if isinstance(param_set,dict)==True:
						param_set.update(param_data)
					else:
						param_set=param_data
				else:
					param_set=param_data

				Device.objects.filter(device_id=device_id).update(param_set=param_set)
				result=[{'device_id':device_id,'param_set':param_set}]
				res.code=1000
				res.data =param_set
				return Response(res.dict)

			return Response(res.dict)

		elif key=='device_set':
			result='ok'
			param_data=request.data.get('param_data')
			device_id=str(param_data['device_id'])
			set_command=param_data['set_command']
			set_value=str(param_data['set_value'])
			dev_detail=Device.objects.get(device_id=device_id)
			dev_model='0'
			if dev_detail!=None:
				dev_model=eval(dev_detail.dynamic)['receive_port']

			set_data='0'
			new_set={}
			new_set[set_command]=set_value
			if dev_detail.param_set!='0':
				if isinstance(eval(dev_detail.param_set),dict)==True:
					set_data=eval(dev_detail.param_set)
					if set_command=='phonebook':
						phonebook=set_data.get('phb')
						save_value=param_data.get('set_value').split(',')
						save_value={save_value[0]:{'name':save_value[1],'num':save_value[2]}}
						if phonebook==None:
							phonebook={}
						phonebook.update(save_value)
						set_data.update({'phb':phonebook})
					elif set_command=='del_phonebook':
						phonebook=set_data.get('phb')
						del_phonebook=phonebook.pop(set_value)#setvalue是id号
						set_value=set_value+','+del_phonebook['name']+','+del_phonebook['num']
						set_data.update({'phb':phonebook})
					else:
						set_data.update(new_set)
				else:
					set_data=new_set
			else:
				set_data=new_set
			# print('set_data=====>',set_data)
			if set_data!='0' and dev_model!='0':
				result=set_param(dev_model,device_id,set_command,set_value)
				Device.objects.filter(device_id=device_id).update(param_set=str(set_data))

				res.code=1000
				res.data = set_data
				return Response(res.dict)

		elif key=='health_reports':

			param_data=request.data.get('param_data')
			device_id=param_data['device_id']
			# 获取设备类型，计算运动步数，三基设备累计总步数，即爱设备每天步数清零
			# dev_detail=Device.objects.filter(device_id=device_id).first()
			# dev_dynamic=eval(dev_detail.dynamic)
			# dev_model=dev_dynamic['receive_port'][1]

			time_data=param_data['time']
			now = time.time()
			midnight = now - (now % 86400) + time.timezone
			s_time = midnight - 86400*int(time_data)
			s_time = datetime.datetime.strptime(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(s_time)), "%Y-%m-%d %H:%M:%S")
			s_time=str(s_time)
				# print(s_time,e_time)
			e_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
			refresh_session(device_id)
			repo_data=start_cacu(device_id,s_time,e_time)
			def change_data(d,m):
				if d!=0 and d!='0':
					d=round(d/m,1)
				return d
			repo_data['sleep_time']=change_data(repo_data['sleep_time'],3600)
			repo_data['stop_time']=change_data(repo_data['stop_time'],3600)
				
			res.data = repo_data

			return Response(res.dict)

		
		elif key=='get_trail':

			map_kind = request.META.get("HTTP_MAP", "")

			start=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
			param_data=request.data.get('param_data')
			# print(map_kind,param_data)
			device_id=param_data['device_id']
			s_time=param_data['s_time']
			e_time=param_data['e_time']

			# 卫星轨迹点 ，wifi轨迹点，lbs轨迹点等，或者混合点
			track_kind=param_data['track_kind']
			refresh_session(device_id)
			sql_content=''
			
			sql_content = 'select * from "'+device_id+'" where serv_receive between \''+s_time+'\' and \''+e_time+'\''
			

			dev_data = pd.read_sql_query(sql_content,engine)

			def get_address_from_wifilbs(trail,track_kind):

				res={'lng':'0','lat':'0'}

				if trail['lng']!='0' and trail['lat']!='0' and 'satelite' in track_kind:
					res={'lng':trail['lng'],'lat':trail['lat']}

				elif trail['wifi']!='0' and 'wifi' in track_kind:
					result=get_wifi_address(trail['wifi'],trail['device_id'])
					if result[0]!='0' and result[1]!='0':
						res={'lng':result[0],'lat':result[1]}


				elif trail['lbs']!='0' and 'lbs' in track_kind:
					result=get_lbs_address(trail['lbs'],trail['device_id'])
					if result[0]!='0' and result[1]!='0':
						res={'lng':result[0],'lat':result[1]}


				return res

			print(dev_data.shape[0])
			if dev_data.shape[0]>1:
				dev_data.loc[:,'trail']=dev_data.apply(lambda x:get_address_from_wifilbs(x,track_kind),axis=1)
				dev_data.loc[:,'lng']=dev_data['trail'].map(lambda x:x['lng'])
				dev_data.loc[:,'lat']=dev_data['trail'].map(lambda x:x['lat'])
				dev_data=dev_data.loc[dev_data['lng']!='0']
				dev_data=dev_data.loc[dev_data['lat']!='0']
				
			if dev_data.shape[0]>1:
				dev_data['lng'] = pd.to_numeric(dev_data['lng'])
				dev_data['lat'] = pd.to_numeric(dev_data['lat'])
				# 坐标系转换bd:百度,gd:高德
				if map_kind=='bd':
					dev_data.loc[:,'change_lnglat']=dev_data.apply(lambda x:wgs84_to_bd09(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
				elif map_kind=='gd':
					dev_data.loc[:,'change_lnglat']=dev_data.apply(lambda x:wgs84_to_gcj02(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
				dev_data['lng']=dev_data.apply(lambda x:x['change_lnglat']['lng'] if x['change_lnglat']!='0' else x['lng'],axis=1)
				dev_data['lat']=dev_data.apply(lambda x:x['change_lnglat']['lat'] if x['change_lnglat']!='0' else x['lat'],axis=1)
				# 与上一个点经纬度一的轨迹点，过滤掉。
				dev_data.loc[:,'trail_sub']=dev_data['lng']-dev_data['lng'].shift(1)
				dev_data=dev_data.loc[dev_data['trail_sub']!=0]
				# 轨迹点多的时候，传输时间过长，去掉不需要的字典，减少传输时间。
				dev_data=dev_data.drop(['lbs',
										'trail',
										'change_lnglat',
										'trail_sub',
										'wifi',
										'rssi',
										'obd',
										'status',
										'battery',
										'sos_alarm',
										'hard_verson',
										'mileage',
										'oil_use',
										'efence_alarm',
										'speed_alarm',
										'stop_time',
										'heart_alarm',
										'blood_alarm',
										'location',
										'othermesg',
										'scanner'], axis=1)
				# print('dev_data========>11111',dev_data['dev_upload'],dev_data['serv_receive'],dev_data['lng'])
				
				dev_data=dev_data.drop_duplicates('serv_receive')
				dev_data=dev_data.sort_values('serv_receive')
				# print('dev_data========>22222',dev_data)
				if dev_data.shape[0]>1:
					dev_data=json.loads(dev_data.to_json(orient="records",force_ascii=False))
				else:
					dev_data=[]

			else:
				dev_data=[]

			print('end_trail_compute',start,datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
			result={'trail_point':dev_data}
			res.code=1000
			res.data = result
			return Response(res.dict)

		# 报警信息处理

		elif key=='alarm_handle':

			param_data=request.data.get('param_data')
			alarm_id=param_data.pop('id')
			Alarm.objects.filter(id=alarm_id).update(handle=param_data['handle'])

			user_tree=[]
			# 下级用户列表
			subordinate_user=[]
			# 本次请求的用户名
			user=str(request.user)
			# 获取用户的树状结构信息，并把下级用户信息加入subordinate_user列表
			get_user_tree(user,Myuser,user_tree,subordinate_user)

			alarm_data=list(Alarm.objects.filter(owner__in=subordinate_user).filter(handle='no').values())

			result={'alarm_data':alarm_data}
			res.code=1000
			res.data = result

			return Response(res.dict)

		elif key=='handle_user_password':

			old_password=request.data.get('old_password')
			new_password=request.data.get('new_password')
			username=request.user
			user = authenticate(username=username, password=old_password)

			if user is not None:
				user.set_password(new_password)
				user.save()
				res.code=1000
				res.data = {'msg':'成功'}
				return Response(res.dict)
			else:
				res.code=1234
				res.data = {'msg':'失败'}

				return Response(res.dict)

		# 用户基本设置处理
		elif key=='handle_user_self':

			param_data=request.data.get('param_data')
			# print(param_data)
			param_to_db=Myuser.objects.filter(username=request.user).first()
			character=eval(param_to_db.character)
			result=''
			#显示图标，判断过来的数据是否超过100字节，超过说明是baase64的数据进行生成图片处理，把路径更新
			if param_data.get('user_icon')!=None:
				user_icon=param_data.pop('user_icon')
				if len(user_icon)>100:
					sys_platform=sys.platform[0:3]

					# 创建路径，有的话不用理会
					save_path=''
					if sys_platform=='win':
						save_path="E:\\tracker\\tracker_app\\static\\data_from_web\\user\\{0}\\".format(str(request.user))
					else:
						save_path="/root/tracker/tracker_app/static/data_from_web/user/{0}/".format(str(request.user))
					
					if not os.path.exists(save_path):  # 判断当前路径是否存在，没有则创建new文件夹/root/device
						os.makedirs(save_path)
					with open(save_path +'system_icon.png', "wb") as f:
						user_icon=user_icon.split(',')[1]
						img = base64.b64decode(user_icon)
						f.write(img)
						character['user_icon']='/static/data_from_web/user/'+str(request.user)+'/system_icon.png'
						f.close()
						
				print(character)
				Myuser.objects.filter(username=request.user).update(character=str(character))
				result='success'

			if result=='success':
				res.code=1000
				res.data = {'user_icon':character['user_icon']}
				return Response(res.dict)
			else:
				res.code=1234
				res.data = {'msg':'失败'}

				return Response(res.dict)

			return HttpResponse(json.dumps('ok'))

		elif key=='phone_user_bind_dev':

			res=BaseResponse()
			param_data=request.data.get('param_data')
			print(param_data)
			device_id=param_data.get('device_id','')
			auth_id=param_data.get('auth_id','')
			nickname=param_data.get('nickname',None)
			dev_detail=Device.objects.filter(device_id=device_id).first()
			if dev_detail!=None:
				if auth_id==dev_detail.auth_id:
					print(request.user,str(request.user))
					phone_user=Myuser.objects.get(username=str(request.user))
					character=eval(phone_user.character)
					bind_dev=''
					if character.get('bind_dev')!=None:
						bind_dev=character['bind_dev']
						bind_dev.append(device_id)
						bind_dev=list(set(bind_dev))
						character['bind_dev']=bind_dev
					else:
						bind_dev=[device_id]
						character['bind_dev']=bind_dev
					character=str(character)
					Myuser.objects.filter(username=request.user).update(character=character)
					if nickname!=None:
						Device.objects.filter(device_id=device_id).update(user_name=nickname)
					device_data=get_phone_user_dev(bind_dev)
					res.code=1000
					# res.data=device_data
				else:
					res.code=1024
					res.error='授权码错误'
				return Response(res.dict)
			else:
				res.code = 1024
				res.error = "无此设备号"

			return Response(res.dict)


		return Response(res.dict)

class CommandView(APIView):

	def get(self, request):
		"""
		根据携带的key,来区分功能需求
		key=car, key=person, key=all
		"""
		res = BaseResponse()

		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		username=Myuser.objects.get(id=user_id).username
		request.user=username
		user_id=mesg_redis.get(token)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		key = request.query_params.get('key', "")
		print(key)


		return Response(res.dict)

	def post(self, request):
		"""
		根据携带的key,来区分功能需求
		key=car, key=person, key=all
		"""
		res = BaseResponse()

		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		username=Myuser.objects.get(id=user_id).username
		request.user=username
		user_id=mesg_redis.get(token)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		key = request.query_params.get('key', "")
		print(key)
		if key=='get_command_log':
			param_data=request.data.get('param_data')
			device_id=param_data['device_id']
			s_time=param_data['s_time']
			e_time=param_data['e_time']

			refresh_session(device_id)
			receive_data=Multi_Media.objects.filter(receiver=device_id).filter(send_time__lt=e_time).filter(send_time__gt=s_time).values()
			# print(receive_data)
			send_data=Multi_Media.objects.filter(sender=device_id).filter(send_time__lt=e_time).filter(send_time__gt=s_time).values()
			chat_data=list(receive_data)+list(send_data)
			res.code=1000
			res.data={'all_data':chat_data}
			return Response(res.dict)

		elif key=='send_command':
			param_data=request.data.get('param_data')
			print(param_data)
			command_style=param_data.pop('command_style')
			if param_data.get('send_time')==None:
				param_data['send_time']=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
			result=handle_command(param_data,username,command_style)

			res.data=result

			return Response(res.dict)


class ChatAPIView(APIView):
	"""设备交互信息处理，语音，文字，图片，视频"""
	def get(self, request):
		"""
		根据携带的key,来区分功能需求
		key=car, key=person, key=all
		"""
		res = BaseResponse()

		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		username=Myuser.objects.get(id=user_id).username
		request.user=username

		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		key = request.query_params.get('key', "")
		print(key)


		return Response(res.dict)

	def post(self, request):
		"""
		根据携带的key,来区分功能需求
		key=car, key=person, key=all
		"""
		res = BaseResponse()

		token = request.META.get("HTTP_AUTHORIZATION", "")
		user_id=mesg_redis.get(token)
		username=Myuser.objects.get(id=user_id).username
		request.user=username
		user_id=mesg_redis.get(token)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return Response(res.dict)

		key = request.query_params.get('key', "")
		print(key)
		if key=='get_chat':
			param_data=request.data.get('param_data')
			param_data['kind']=['voice','text','picture']
			chat_data=get_chat(param_data)

			res.data={'all_data':chat_data}
			return Response(res.dict)

		elif key=='send_chat':
			param_data=request.data.get('param_data')
			print('ChatAPIView======================')
			if param_data.get('platform')!=None and param_data.get('set_command')=='voice':
				voice=param_data['set_value']
				voice=voice.split(',')
				# content=voice[1]
				content=base64.b64decode(voice[1])
				send_time=param_data['send_time']
				file_path=save_to_file(param_data['device_id'],content,send_time)
				if os.path.exists(file_path[0]):
					ffmpy3.FFmpeg(inputs={file_path[0]: None}, outputs={file_path[1]: ['-ac','1','-ar','8000']}).run()
					voice[1]=open(file_path[1],'rb').read()
					voice[1]=base64.b64encode(voice[1]).decode()
					voice=','.join(voice)
					param_data['set_value']=voice
				
			command_style=param_data.pop('command_style')
			result=handle_command(param_data,username,command_style)
			res.data={'msg':result}

			return Response(res.dict)


# 把音频，图片等存储在本地的函数
def save_to_file(device_id,content,send_time):
	# 转换成时间数组
	# now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	timeArray = time.strptime(send_time, "%Y-%m-%d %H:%M:%S")
	# 转换成时间戳
	timestamp = time.mktime(timeArray)
	# if x == 'tk_mesg':
	# 	send_name = 'amr'
	# elif x == 'img_data':
	# 	send_name = 'jpeg'
	# 获取当前设备号,获取现在的时间年月日,获取现在时间的时间戳时间,然后存入文件中
	pk_name = "{}.{}".format(int(timestamp), 'mp3')
	pk_name1 = "{}.{}".format(int(timestamp), 'amr')
	plat_form=sys.platform[0:3]
	save_path=''
	if plat_form=='win':
		save_path="E:\\tracker\\tracker_app\\static\\multi_data\\{0}\\{1}\\".format(device_id, datetime.datetime.now().strftime('%Y-%m-%d'))
	else:
		save_path="/root/tracker/tracker_app/static/multi_data/{0}/{1}/".format(device_id, datetime.datetime.now().strftime('%Y-%m-%d'))
	
	if not os.path.exists(save_path):  # 判断当前路径是否存在，没有则创建new文件夹/root/device
		os.makedirs(save_path)
	with open(save_path + pk_name, "wb") as f:
		f.write(content)

	src_path=save_path+pk_name
	src_path1=save_path+pk_name1
	return [src_path,src_path1]


# 短信验证码发送
import hashlib
def send_sms(Verification,phone,time):
	"""发送短信验证码"""

	random = Verification

	# print(Verification,phone,time)
	sigsdata = 'appkey=a646ca2f3eeec4cf8ff5bcd031f4d23b&random='+random+'&time=' + time + '&mobile=' + phone
	hash  = hashlib.sha256()
	hash.update(sigsdata.encode("utf8"))
	sigs = hash.hexdigest()
	url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms?sdkappid=1400305225&random=" + random
	# print('url---',url)
	data ={
		'ext':'',
		'extend':'',
		'params':[Verification,'2'],
		'sig':sigs,
		'sign':'深圳简易通科技',
		'tel':{
			'mobile':phone,
			'nationcode':'86',
		},
		'time':time,
		'tpl_id':'518930'
	}
	data = json.dumps(data)
	res = requests.post(url,data)
	return res.text



# 用户手机注册账号
class RegisteredView(APIView):

	def post(self, request):
		'''注册'''
		key = request.query_params.get('key', "")
		print(key)
		res = BaseResponse()
		if key == 'validation':
			phone = request.data.get('phone','')
			if phone:
				user_obj = Myuser.objects.filter(username=phone).first()
				if user_obj:
					res.code = 1024
					res.error = "该手机号已注册"
					return Response(res.dict)
				elif len(phone) > 11 or len(phone) < 11:
					res.code = 1024
					res.error = "请输入正确的手机号"
					return Response(res.dict)
				else:
					verification_code = str(random.randint(100000,999999))
					now_time = str(int(time.time()))
					sms = send_sms(verification_code,phone,now_time)#发送短信
					res.code=1000
					res.data = {"msg":"发送成功"}
					mesg_redis.set(phone,verification_code,ex=600)
					return Response(res.dict)
			else:
				res.code = 1024
				res.error = "请携带手机号"
				return Response(res.dict)
		elif key == 'registered':
			phone = request.data.get('phone','')
			password = request.data.get('password','')
			validation = request.data.get('validation','')
			if phone and password and validation:
				user_obj = Myuser.objects.filter(username=phone).first()
				if user_obj:
					res.code = 1024
					res.error = "该手机号已注册"
					return Response(res.dict)
				else:
					verification_code = mesg_redis.get(phone)
					if verification_code==None:
						res.code = 1024
						res.error = "验证码已过期，请重新获取"
						return Response(res.dict)
					else:
						if verification_code == validation:
							Myuser.objects.create_user(
									username=phone, visible_name=phone,level='0',
									email='0', leader='0', status='on',
									subordinate="0",character="{'kind':'phone_user','user_icon':'/static/img/default.png','refresh_time':'60','alarm_audio':'on','alarm_show':'on','handle_device':'no'}",remark='0')
							res.data = {"msg":"注册成功"}
							res.code=1000
							return Response(res.dict)
						else:
							res.code = 1024
							res.error = "验证码错误"
							return Response(res.dict)
			else:
				res.code = 1024
				res.error = "请携带参数"
				return Response(res.dict)

		

		else:
			res.code = 1024
			res.error = "请携带参数"
			return Response(res.dict)

# 重置密码
class Retrieve_passwordView(APIView):
	def post(self, request):
		"""找回密码"""
		key = request.GET.get('key', "")
		print(key)
		res = BaseResponse()
		phone = request.data.get('phone','')
		v_code = request.data.get('validation_code','')
		pwd = request.data.get('password','')

		if request.method=='POST':
			if key == 'validation':
				if phone:
					user_obj = Myuser.objects.filter(username=phone).first()
					if user_obj:
						verification_code = str(random.randint(100000,999999))
						now_time = str(int(time.time()))
						# print(verification_code,phone,now_time)
						sms = send_sms(verification_code,phone,now_time)#发送短信
						res.code=1000
						res.data = "发送成功"
						mesg_redis.set(phone,verification_code,ex=600)
						return Response(res.dict)
					else:
						res.code = 1024
						res.error = "该手机号尚未注册"
						return Response(res.dict)
				else:
					res.code = 1024
					res.error = "请携带手机号"
					return Response(json.dumps(res.dict))
			elif key == 'check_v_code':
				if phone and v_code:
					verification_code = mesg_redis.get(phone)
					if verification_code==None:
						res.code = 1024
						res.error = "验证码已过期，请重新获取"
						return Response(res.dict)
					else:
						if verification_code == v_code:
							return Response(res.dict)
						else:
							res.code = 1024
							res.error = "验证码错误"
							return Response(res.dict)
				else:
					res.code = 1024
					res.error = "请携带参数"
					return Response(res.dict)

			elif key == 'reset_pwd':
				if phone and pwd:
					user = User.objects.get(username=phone)
					if user is not None:
						user.set_password(pwd)
						user.save()
						res.code=1000
						res.data='重置密码成功'
						return Response(res.dict)
					else:
						res.code = 1024
						res.error = "无此用户，重置密码失败"
						return Response(res.dict)
				else:
					res.code = 1024
					res.error = "请携带参数"
					return Response(res.dict)
			else:
				res.code = 1024
				res.error = "请携带参数"
				return Response(res.dict)


def handle_trail(device_id,s_time,e_time,track_kind,map_kind='bd'):
	sql_content=''
	
	sql_content = 'select * from "'+device_id+'" where serv_receive between \''+s_time+'\' and \''+e_time+'\''
	

	dev_data = pd.read_sql_query(sql_content,engine)

	def get_address_from_wifilbs(trail,track_kind):

		res={'lng':'0','lat':'0'}

		if trail['lng']!='0' and trail['lat']!='0' and 'satelite' in track_kind:
			res={'lng':trail['lng'],'lat':trail['lat']}

		elif trail['wifi']!='0' and 'wifi' in track_kind:
			result=get_wifi_address(trail['wifi'],trail['device_id'])
			if result[0]!='0' and result[1]!='0':
				res={'lng':result[0],'lat':result[1]}


		elif trail['lbs']!='0' and 'lbs' in track_kind:
			result=get_lbs_address(trail['lbs'],trail['device_id'])
			if result[0]!='0' and result[1]!='0':
				res={'lng':result[0],'lat':result[1]}


		return res

	print(dev_data.shape[0])
	if dev_data.shape[0]>1:
		# 排序和重置index索引 2020.09.04吕康宁
		dev_data=dev_data.sort_values('serv_receive')
		dev_data=dev_data.reset_index(drop=True)
		dev_data.loc[:,'trail']=dev_data.apply(lambda x:get_address_from_wifilbs(x,track_kind),axis=1)
		dev_data['lng']=dev_data['trail'].map(lambda x:x['lng'])
		dev_data['lat']=dev_data['trail'].map(lambda x:x['lat'])
		dev_data=dev_data.loc[dev_data['lng']!='0']
		dev_data=dev_data.loc[dev_data['lat']!='0']
		
	if dev_data.shape[0]>1:
		dev_data['lng'] = pd.to_numeric(dev_data['lng'])
		dev_data['lat'] = pd.to_numeric(dev_data['lat'])
		# 坐标系转换bd:百度,gd:高德
		if map_kind=='bd':
			dev_data.loc[:,'change_lnglat']=dev_data.apply(lambda x:wgs84_to_bd09(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
		elif map_kind=='gd':
			dev_data.loc[:,'change_lnglat']=dev_data.apply(lambda x:wgs84_to_gcj02(x['lng'],x['lat']) if x['lng']!='0' else '0',axis=1)
		dev_data['lng']=dev_data.apply(lambda x:x['change_lnglat']['lng'] if x['change_lnglat']!='0' else x['lng'],axis=1)
		dev_data['lat']=dev_data.apply(lambda x:x['change_lnglat']['lat'] if x['change_lnglat']!='0' else x['lat'],axis=1)
		# 与上一个点经纬度一的轨迹点，过滤掉。
		dev_data.loc[:,'lng_sub']=dev_data['lng']-dev_data['lng'].shift(1)
		dev_data.loc[:,'lat_sub']=dev_data['lat']-dev_data['lat'].shift(1)
		dev_data=dev_data.loc[(dev_data['lng_sub']!=0) & (dev_data['lat_sub']!=0)]
		# 轨迹点多的时候，传输时间过长，去掉不需要的字典，减少传输时间。
		dev_data=dev_data.drop(['lbs',
								'trail',
								'change_lnglat',
								'lng_sub',
								'lat_sub',
								'wifi',
								'rssi',
								'obd',
								'status',
								'battery',
								'sos_alarm',
								'hard_verson',
								'mileage',
								'oil_use',
								'efence_alarm',
								'speed_alarm',
								'stop_time',
								'heart_alarm',
								'blood_alarm',
								'location',
								'othermesg',
								'scanner'], axis=1)
		# print('dev_data========>11111',dev_data['dev_upload'],dev_data['serv_receive'],dev_data['lng'])
		
		dev_data=dev_data.drop_duplicates('serv_receive')
		# print('dev_data========>22222',dev_data)
		if dev_data.shape[0]>1:
			dev_data=json.loads(dev_data.to_json(orient="records",force_ascii=False))
		else:
			dev_data=[]

	else:
		dev_data=[]

	return dev_data


# 视频通话功能相关
# import subprocess
# my_ffmpeg = subprocess.Popen('ffmpeg -re -i - -c copy -f flv rtmp://139.199.9.116:1935/jt808video/test1',
# 					 stdin=subprocess.PIPE, shell=True)
# my_ffmpeg = subprocess.Popen('ffmpeg -re -i - -c copy -f flv rtmp://139.199.9.116:1935/hls/test1',
# stdin=subprocess.PIPE, shell=True)
# if request.is_websocket():
# 	WebSocket = request.websocket
	
# 	i=0
# 	while True:
# 		client_msg = WebSocket.read()
# 		# print('client_msg==>',client_msg)
# 		if client_msg!=None:
# 			client_msg=client_msg.decode()
# 			if client_msg=='stop':
# 				my_ffmpeg.stdin.close()
# 				break
# 			client_msg=base64.b64decode(client_msg)
# 			print('client_msg==>',client_msg)
# 			my_ffmpeg.stdin.write(client_msg)					 
@accept_websocket
@csrf_exempt
def interact(request):
	print(request.user)
	# print(vars(request))
	user=str(request.user)
	# 校验用户登录情况
	if user=='AnonymousUser':
		res = BaseResponse()
		token = request.META.get("HTTP_AUTHORIZATION", "")
		print('token====>',token)
		user_id=mesg_redis.get(token)
		print('token====>',user_id)
		if user_id==None:
			res.code=1234
			res.error='token错误'
			return HttpResponse(res.dict)

		username=Myuser.objects.get(id=user_id).username
		request.user=username

	res=''


	if request.is_websocket(): # 如果请求是websocket请求：

		WebSocket = request.websocket
		client_msg=''
		messages={}
		i=0
		while True:
			i += 1 # 递增次数 i 

			# 休眠1秒
			time.sleep(5)

			# 设置发送前端的数据
			print(client_msg,WebSocket.has_messages())
			if WebSocket.has_messages():
				client_msg = WebSocket.read()
				if client_msg!=None:
					client_msg=client_msg.decode()
					if client_msg=='stop_websocket':
						break

			if client_msg!=None:
				dev_table=Device_Base.classes[client_msg]
				dev_newest=session.query(dev_table).order_by(dev_table.id.desc()).first()
				dev_newest=vars(dev_newest)
				dev_newest.pop('_sa_instance_state')
				# print('dev_newest_counts',i,dev_newest)

				media_data=Multi_Media.objects.filter(sender=client_msg).order_by('-id').first()
				media_data=vars(media_data)
				media_data.pop('_state')
				# print(media_data)
				
				if dev_newest['lng']=='0' and dev_newest['lat']=='0':
					result=['0','0']
					if dev_newest['wifi']!='0':
						result=get_wifi_address(dev_newest['wifi'],dev_newest['device_id'])
					elif dev_newest['lbs']!='0':
						result=get_lbs_address(dev_newest['lbs'],dev_newest['device_id'])

					dev_newest['lng']=result[0]
					dev_newest['lat']=result[1]

				if messages.get('dynamic')==None:
					messages = {'dynamic':dev_newest['id'],'media':media_data['id']}
				else:
					if messages['dynamic']==dev_newest['id']:
						dev_newest='no_change'
					else:
						messages['dynamic']=dev_newest['id']
					if messages['media']==media_data['id']:
						media_data='no_change'
					else:
						messages['media']=media_data['id']

				send_data={'dynamic':dev_newest,'media':media_data}

			if i>300:
				break

			request.websocket.send(json.dumps(send_data))
		request.websocket.send('websocket end')
	else:
		print('not WebSocket')

		key=request.GET.get('what')
		param_data=eval(request.POST.get('param_data'))

		if key=='send_chat':
			req_user=str(request.user)
			print('interact======================')
			res=handle_command(param_data,req_user,'chat')

		elif key=='get_chat':
			res=get_chat(param_data)

	return HttpResponse(json.dumps(res))


def get_chat(param_data):

	device_id=param_data['device_id']
	s_time=param_data['s_time']
	e_time=param_data['e_time']
	kind=param_data['kind']
	# print(param_data)
	# 刷新数据库连接，防止已存储的数据没有映射上来。
	refresh_session(device_id)
	# print(Command_Log.objects.filter(device_id=device_id).all().values())
	receive_data=Multi_Media.objects.filter(receiver=device_id).filter(content_kind__in=kind).filter(send_time__lt=e_time).filter(send_time__gt=s_time).values()
	send_data=Multi_Media.objects.filter(sender=device_id).filter(content_kind__in=kind).filter(send_time__lt=e_time).filter(send_time__gt=s_time).values()
	chat_data=list(receive_data)+list(send_data)
	# 按照时间排序
	order_data=pd.DataFrame(chat_data)
	
	if order_data.shape[0]>0:
		order_data=order_data.sort_values('send_time')
		order_data=json.loads(order_data.to_json(orient="records",force_ascii=False))
	else:
		order_data=[]

	return order_data



# 暂时不用子线程执行命令
# set_param_thread=threading.Thread(target=set_param,args=(dev_dynamic['receive_port'],device_id,set_command,send_data,request.user))
# set_param_thread.start()
# 命令处理，获取命令信息，
def handle_command(param_data,owner,command_style):
	result='0'
	# 命令下发的必要参数取并校验
	for x in param_data:
		if x!='set_value':
			if param_data[x]=='' or param_data[x]=='0' or param_data[x]==0:
				return 'param null'
	dev_id=str(param_data['device_id'])#谜题-在interact.html里面该参数为string，一模一样的命令下发代码，在dynamic页面中，该参数到这里变成了num，之前都是正常的
	comd=param_data['set_command']
	value=param_data['set_value']
	send_time=param_data['send_time']
	port=param_data['port']#接收的端口和设备品牌
	
	device_model=port[1]
	port=port[0]
	if device_model in command:
		param=eval(command[device_model]+'(dev_id,comd,value,device_model,owner)')
		print(param)
		# 设备不支持的命令，不用建立command_log表格
		if param=='':
			result='unsupport command'
		else:
			
			# 命令log存库的名称
			comd_id=dev_id+comd+send_time
			# 图片和语音的数据量较大，本地文件存储，数据库存储文件路劲，在执行完毕的时候存储
			comd_log_value=value
			if comd in ['voice','picture']:
				comd_log_value=''
			# 命令执行记录
			comd_log=dict(command_id=comd_id,
							device_id=dev_id,
							command_name=comd,
							command_style=command_style,
							command_value =comd_log_value,
							send_time=send_time,
							owner=owner)
			Command_Log.objects.create(**(comd_log))
			comd_table_id=Command_Log.objects.get(command_id=comd_id).id
			# 命令表完整放到redis，供analysis模块执行完毕相应命令的是，更新执行结果
			command_detail={'id':comd_table_id,'command_id':comd_id,'command_name':comd,'command_value':value,'send_time':send_time,'command_style':command_style,'device_id':dev_id,
						 'command_result':'0','remark':'0','owner':owner}

			param_data={'device_id':dev_id,'param':param,'command_name':comd,'command_detail':command_detail}
			ip_port = ('localhost',port)
			sk = socket.socket()
			mesg_redis.lpush('set_param',str(param_data))
			sk_res=sk.connect_ex(ip_port)
			# print('sk_res====>',sk_res)
			if sk_res!=0:
				result=sk_res
			else:
				result = sk.recv(1024)
				result = result.decode()
				sk.close()
	else:
		result='command file not found!'

	print(result)
	return result

